home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 2 / ETO Development Tools 2.iso / Tools - Objects / MacApp / MacApp CD Release / MacApp 2.0.1 (Many Libraries) / Libraries / UMacApp.TView.p < prev    next >
Encoding:
Text File  |  1990-10-25  |  65.3 KB  |  2,668 lines  |  [TEXT/MPS ]

  1. {$P}
  2. {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]}
  3. { UMacApp.TView.p }
  4. { Copyright © 1984-1990 Apple Computer Inc.  All rights reserved. }
  5.  
  6. {--------------------------------------------------------------------------------------------------}
  7. {$S MAOpen}
  8.  
  9. PROCEDURE TView.IView(itsDocument: TDocument;
  10.                       itsSuperview: TView;
  11.                       itsLocation: VPoint;
  12.                       itsSize: VPoint;
  13.                       itsHSizeDet, itsVSizeDet: SizeDeterminer);
  14.  
  15.     VAR
  16.         fi:                 FailInfo;
  17.  
  18.     PROCEDURE HandleFailure(error: OSErr;
  19.                             message: LONGINT);
  20.  
  21.         BEGIN
  22.         Free;
  23.         END;
  24.  
  25.     BEGIN
  26.     fSuperview := itsSuperview;
  27.     fSubViews := NIL;
  28.     fDocument := itsDocument;
  29.     fLocation := itsLocation;
  30.     fSize := itsSize;
  31.     fSizeDeterminer[h] := itsHSizeDet;
  32.     fSizeDeterminer[v] := itsVSizeDet;
  33.     fHLDesired := hlOff;
  34.     fIdentifier := kNoIdentifier;
  35.     fShown := TRUE;
  36.     fViewEnabled := TRUE;
  37.     fPrintHandler := NIL;
  38.  
  39.     {$IFC qExperimentalAndUnsupported}
  40.     fFocusRec.Clip := NIL;
  41.     fFocusRec.IsValid := FALSE;
  42.     {$EndC}
  43.  
  44.     IEvtHandler(itsSuperview);
  45.  
  46.     CatchFailures(fi, HandleFailure);
  47.  
  48.     {$IFC qExperimentalAndUnsupported}
  49.     fFocusRec.Clip := MakeNewRgn;
  50.     fFocusRec.isValid := FALSE;
  51.     {$EndC}
  52.  
  53.     IF itsSuperview <> NIL THEN
  54.         itsSuperview.AddSubView(SELF);
  55.     IF itsDocument <> NIL THEN
  56.         itsDocument.AddView(SELF);
  57.     Success(fi);
  58.     END;
  59.  
  60. {--------------------------------------------------------------------------------------------------}
  61. {$S MAOpen}
  62.  
  63. PROCEDURE TView.IRes(itsDocument: TDocument;
  64.                      itsSuperview: TView;
  65.                      VAR itsParams: Ptr);
  66.  
  67.     BEGIN
  68.     WITH ViewTemplatePtr(itsParams)^ DO
  69.         BEGIN
  70.         IView(itsDocument, itsSuperview, itsLocation, itsSize, SizeDeterminer(itsHSizeDet),
  71.               SizeDeterminer(itsVSizeDet));
  72.         fShown := isShown;
  73.         fViewEnabled := isEnabled;
  74.         fHLDesired := hlOff;
  75.         fIdentifier := thisViewID;
  76.         OffsetPtrWStr(itsParams, SIZEOF(ViewTemplate));
  77.         END;
  78.     END;
  79.  
  80. {--------------------------------------------------------------------------------------------------}
  81. {$S MAWriteRes}
  82.  
  83. PROCEDURE TView.WRes(theResource: ViewRsrcHndl;
  84.                      VAR itsParams: Ptr);
  85.  
  86.     VAR
  87.         vwPtr:                ViewTemplatePtr;
  88.  
  89.     BEGIN
  90.     vwPtr := ViewTemplatePtr(ExpandPtrWStr(theResource, itsParams, SIZEOF(ViewTemplate),
  91.                                            LENGTH(gWResType)));
  92.  
  93.     WITH vwPtr^ DO
  94.         BEGIN
  95.         IF fSuperview <> NIL THEN
  96.             itsParentID := fSuperview.fIdentifier
  97.         ELSE
  98.             itsParentID := kNoIdentifier;
  99.         thisViewID := fIdentifier;
  100.         itsLocation := fLocation;
  101.         itsSize := fSize;
  102.         itsVSizeDet := fSizeDeterminer[v];
  103.         itsHSizeDet := fSizeDeterminer[h];
  104.         isShown := fShown;
  105.         isEnabled := fViewEnabled;
  106.         itsSignature := gWResSignature;
  107.         { itsType := gWResType; }
  108.         CopyStr255(gWResType, PRStr(itsType));
  109.         END;
  110.  
  111.     { Everybody gets this far - bump number of views in resource by 1 }
  112.     WITH theResource^^ DO
  113.         numViews := numViews + 1;
  114.     END;
  115.  
  116. {--------------------------------------------------------------------------------------------------}
  117. {$S MAWriteRes}
  118.  
  119. PROCEDURE TView.WriteRes(theResource: ViewRsrcHndl;
  120.                          VAR itsParams: Ptr);
  121.  
  122.     BEGIN
  123.     gWResSignature := 'view'; gWResType := 'TView';
  124.     WRes(theResource, itsParams);
  125.     END;
  126.  
  127. {--------------------------------------------------------------------------------------------------}
  128. {$S MAClose}
  129.  
  130. PROCEDURE TView.Free;
  131.  
  132.     PROCEDURE FreeView(theView: TView);
  133.         BEGIN
  134.         theView.Free;                                    { Type checking is the oat bran of the 70's }
  135.         END;
  136.  
  137.     BEGIN
  138.     { Because RemoveSubView frees the list when it goes empty we don't need to actually free
  139.     the list right here.  When each subview gets the free message it removes itself from the
  140.     superview (SELF) and the list may get deleted.  Kinda twisty, huh? }
  141.     EachSubView(FreeView);
  142.  
  143.     InvalidateFocus;
  144.     gApplication.InvalidateCursorRgn;                    {Must re-calc cursor rgn.}
  145.  
  146.     IF SELF = gTarget THEN                                { Fixup the target chain }
  147.         gApplication.SetTarget(gApplication);
  148.  
  149.     IF fSuperview <> NIL THEN
  150.         fSuperview.RemoveSubView(SELF);
  151.     fSuperview := NIL;
  152.  
  153.     FreeIfObject(fPrintHandler);
  154.     fPrintHandler := NIL;
  155.  
  156.     IF fDocument <> NIL THEN
  157.         fDocument.DeleteView(SELF);
  158.     fDocument := NIL;
  159.  
  160.     {$IFC qExperimentalAndUnsupported}
  161.     IF fFocusRec.Clip <> NIL THEN
  162.         DisposeRgn(fFocusRec.Clip);
  163.     fFocusRec.Clip := NIL;
  164.     fFocusRec.IsValid := FALSE;
  165.     {$EndC}
  166.  
  167.     INHERITED Free;
  168.     END;
  169. {--------------------------------------------------------------------------------------------------}
  170. {$S MAActivate}
  171.  
  172. PROCEDURE TView.Activate(entering: BOOLEAN);
  173.  
  174.     VAR
  175.         newHL:                HLState;
  176.  
  177.     PROCEDURE ActivateSubView(theSubView: TView);
  178.  
  179.         BEGIN
  180.         theSubView.Activate(entering);
  181.         END;
  182.  
  183.     BEGIN
  184.     IF entering THEN
  185.         newHL := hlOn
  186.     ELSE
  187.         newHL := hlDim;
  188.     IF Focus & IsVisible THEN
  189.         DoHighlightSelection(fHLDesired, newHL);
  190.     fHLDesired := newHL;
  191.     EachSubView(ActivateSubView);
  192.     END;
  193.  
  194. {--------------------------------------------------------------------------------------------------}
  195. {$S MAOpen}
  196.  
  197. PROCEDURE TView.AddSubView(theSubView: TView);
  198.  
  199.     BEGIN
  200.     IF theSubView <> NIL THEN
  201.         BEGIN
  202.         { Create the subview list if necessary }
  203.         IF fSubViews = NIL THEN
  204.             BEGIN
  205.             fSubViews := NewList;
  206.             {$IFC qDebug}
  207.             fSubViews.SetEltType('TView');
  208.             {$ENDC}
  209.             END;
  210.         if qDebug & (fSubViews.GetSameItemNo(theSubView) <> kEmptyIndex) THEN
  211.             ProgramBreak('in TView.AddSubView: Attempting to add the same subview twice.');
  212.  
  213.         fSubViews.InsertLast(theSubView);
  214.  
  215.         theSubView.fSuperview := SELF;
  216.         IF theSubView.fNextHandler = NIL THEN            { If necessary, }
  217.             theSubView.fNextHandler := SELF;            { …hook it up to an event hander chain. }
  218.  
  219.         theSubView.InvalidateFocus;                        { the new subview may have been focused }
  220.  
  221.         theSubView.BeInPort(GetGrafPort);
  222.         END;
  223.     END;
  224.  
  225. {--------------------------------------------------------------------------------------------------}
  226. {$S MAViewRes}
  227.  
  228. PROCEDURE TView.AdjustSize;
  229.  
  230.     VAR
  231.         newSize:            VPoint;
  232.  
  233.     PROCEDURE AdjustSubViewSize(theSubView: TView);
  234.  
  235.         BEGIN
  236.         theSubView.AdjustSize;
  237.         END;
  238.  
  239.     BEGIN
  240.     newSize := fSize;
  241.     ComputeSize(newSize);
  242.     {$Push} {$H-}
  243.     IF NOT EqualVPt(newSize, fSize) THEN
  244.     {$Pop}
  245.         BEGIN
  246.         Resize(newSize.h, newSize.v, kInvalidate);
  247.         DoPagination;
  248.         END
  249.     ELSE
  250.         EachSubView(AdjustSubViewSize);
  251.     END;
  252.  
  253. {--------------------------------------------------------------------------------------------------}
  254. {$S MAViewRes}
  255.  
  256. PROCEDURE TView.Adorn(area: Rect;
  257.                       itsPenSize: Point;
  258.                       itsAdornment: CntlAdornment);
  259.  
  260.     CONST
  261.         CntlFrame            = [adnLineTop, adnLineLeft, adnLineBottom, adnLineRight];
  262.  
  263.     VAR
  264.         shadowed:            BOOLEAN;
  265.         savedPenState:        PenState;
  266.  
  267.     PROCEDURE XFrameOval;
  268.  
  269.         BEGIN
  270.         FrameOval(area);
  271.         END;
  272.  
  273.     PROCEDURE XFrameRRect;
  274.  
  275.         BEGIN
  276.         FrameRoundRect(area, 16, 16);
  277.         END;
  278.  
  279.     PROCEDURE DrawWithShadow(PROCEDURE DrawCmd);
  280.  
  281.         LABEL 1;
  282.  
  283.         VAR
  284.             drawRgn:            RgnHandle;
  285.             shadowRgn:            RgnHandle;
  286.             fi:                 FailInfo;
  287.  
  288.         PROCEDURE HandleFailure(error: OSErr;
  289.                                 message: LONGINT);
  290.  
  291.             BEGIN
  292.    { If we fail allocating memory for the regions, dispose of the regions if
  293.     they exist and continue}
  294.             GOTO 1;
  295.             END;
  296.  
  297.         BEGIN
  298.         IF shadowed THEN
  299.             BEGIN
  300.             shadowRgn := NIL;                            {In case we creating drawRgn fails}
  301.             CatchFailures(fi, HandleFailure);
  302.             drawRgn := MakeNewRgn;
  303.             shadowRgn := MakeNewRgn;
  304.  
  305.             OpenRgn;
  306.             DrawCmd;
  307.             CloseRgn(drawRgn);
  308.  
  309.             CopyRgn(drawRgn, shadowRgn);
  310.             OffsetRgn(shadowRgn, itsPenSize.h, itsPenSize.v);
  311.             DiffRgn(shadowRgn, drawRgn, shadowRgn);
  312.             PaintRgn(shadowRgn);
  313.             Success(fi);
  314.         1:
  315.             IF drawRgn <> NIL THEN
  316.                 DisposeRgn(drawRgn);
  317.             IF shadowRgn <> NIL THEN
  318.                 DisposeRgn(shadowRgn);
  319.             END;
  320.         DrawCmd;
  321.         END;
  322.  
  323.     PROCEDURE DrawLine(vhs: VHSelect;
  324.                        lh, lv, lto: INTEGER);
  325.  
  326.         BEGIN
  327.         MoveTo(lh, lv);
  328.         CASE vhs OF
  329.             h:
  330.                 Line(lto - lh, 0);
  331.             v:
  332.                 Line(0, lto - lv);
  333.         END;
  334.         END;
  335.  
  336.     BEGIN
  337.     IF itsAdornment <> [] THEN                            { Only do this if adorning is asked for }
  338.         BEGIN
  339.         {$IFC qDebug}
  340.         AssumeFocused;
  341.         {$ENDC}
  342.         GetPenState(savedPenState);
  343.         PenNormal;
  344.         PenSize(itsPenSize.h, itsPenSize.v);
  345.  
  346.         shadowed := adnShadow IN itsAdornment;
  347.         IF shadowed THEN
  348.             SubPt(itsPenSize, area.botRight);
  349.  
  350.         IF adnOval IN itsAdornment THEN
  351.             DrawWithShadow(XFrameOval);
  352.  
  353.         IF adnRRect IN itsAdornment THEN
  354.             DrawWithShadow(XFrameRRect);
  355.  
  356.         IF itsAdornment >= CntlFrame THEN                { Special case for whole rect! }
  357.             BEGIN
  358.             FrameRect(area);
  359.             IF shadowed THEN
  360.                 WITH area DO
  361.                     BEGIN
  362.                     DrawLine(h, left + itsPenSize.h, bottom, right);
  363.                     DrawLine(v, right, top + itsPenSize.v, bottom);
  364.                     END;
  365.             END
  366.         ELSE
  367.             WITH area DO
  368.                 BEGIN                                    { No shadows for single lines }
  369.                 IF adnLineTop IN itsAdornment THEN
  370.                     DrawLine(h, left, top, right);
  371.                 IF adnLineLeft IN itsAdornment THEN
  372.                     DrawLine(v, left, top, bottom);
  373.                 IF adnLineBottom IN itsAdornment THEN
  374.                     DrawLine(h, left, bottom - itsPenSize.v, right);
  375.                 IF adnLineRight IN itsAdornment THEN
  376.                     DrawLine(v, right - itsPenSize.h, top, bottom);
  377.                 END;
  378.         SetPenState(savedPenState);
  379.         END;
  380.     END;
  381.  
  382. {--------------------------------------------------------------------------------------------------}
  383. {$Push} {$IFC qTrace} {$D+} {$ENDC}
  384. {$S MADebug}
  385.  
  386. PROCEDURE TView.AssumeFocused;
  387.  
  388.     VAR
  389.         myself:             TView;
  390.         aString:            Str255;
  391.         aStringPtr:         MANamePtr;
  392.  
  393.     BEGIN
  394.     IF gAssumeFocused THEN
  395.         IF NOT IsFocused THEN
  396.             BEGIN
  397.             myself := SELF;
  398.             WrLblField('Failed AssumeFocused.  View', @myself, bObject);
  399.             aStringPtr := MANamePtr(@aString);
  400.             GetClassNameFromID(GetClassID(SELF), aStringPtr^);
  401.             Write(', ClassName=', aString, ', InspectorName=');
  402.             GetInspectorName(aString);
  403.             WRITELN(aString);
  404.             ProgramBreak('');
  405.             END;
  406.     END;
  407. {$Pop}
  408.  
  409. {--------------------------------------------------------------------------------------------------}
  410. {$S MAViewRes}
  411.  
  412. PROCEDURE TView.AttachPrintHandler(itsPrintHandler: TPrintHandler);
  413.  
  414.     BEGIN
  415.     fPrintHandler := itsPrintHandler;
  416.     DoCheckPrinter;
  417.     END;
  418.  
  419. {--------------------------------------------------------------------------------------------------}
  420. {$S MANonRes}
  421.  
  422. PROCEDURE TView.BeInPort(itsPort: GrafPtr);
  423.  
  424.     PROCEDURE NotifySubView(theSubView: TView);
  425.  
  426.         BEGIN
  427.         theSubView.BeInPort(itsPort);
  428.         END;
  429.  
  430.     BEGIN
  431.     IF (itsPort <> NIL) & (fPrintHandler <> NIL) THEN
  432.         DoCheckPrinter;
  433.     EachSubView(NotifySubView);
  434.     END;
  435.  
  436. {--------------------------------------------------------------------------------------------------}
  437. {$S MANonRes}
  438.  
  439. PROCEDURE TView.BeInScroller(itsScroller: TScroller);
  440.  
  441.     VAR
  442.         scrollLimits:        VPoint;
  443.  
  444.     BEGIN
  445.     IF itsScroller <> NIL THEN
  446.         BEGIN
  447.         scrollLimits := fSize;
  448.         {$Push} {$H-}
  449.         AddVPt(fLocation, scrollLimits);
  450.         {$Pop}
  451.         itsScroller.SetScrollLimits(scrollLimits, kDontRedraw);
  452.         END;
  453.     END;
  454.  
  455. {--------------------------------------------------------------------------------------------------}
  456. {$S MAViewRes}
  457.  
  458. PROCEDURE TView.CalcMinSize(VAR minSize: VPoint);
  459.  
  460.     BEGIN
  461.     minSize := fSize;
  462.     END;
  463.  
  464. {--------------------------------------------------------------------------------------------------}
  465. {$S MAViewRes}
  466.  
  467. PROCEDURE TView.ClipFurtherTo(r: Rect;
  468.                               hDeltaOrg, vDeltaOrg: INTEGER);
  469. { Set clipping to: (<current clipping> INTERSECT r) OFFSET-BY (hDeltaOrg, vDeltaOrg) }
  470.  
  471.     BEGIN
  472.     {$IFC qDebug}
  473.     AssumeFocused;
  474.     UseTempRgn('ClipFurtherTo');
  475.     {$ENDC}
  476.  
  477.     RectRgn(gTempRgn, r);
  478.     SectRgn(thePort^.clipRgn, gTempRgn, gTempRgn);
  479.     IF (hDeltaOrg <> 0) | (vDeltaOrg <> 0) THEN
  480.         OffsetRgn(gTempRgn, hDeltaOrg, vDeltaOrg);
  481.     SetClip(gTempRgn);
  482.  
  483.     {$IFC qDebug}
  484.     DoneWithTempRgn;
  485.     {$ENDC}
  486.     END;
  487.  
  488. {--------------------------------------------------------------------------------------------------}
  489. {$S MAClose}
  490.  
  491. PROCEDURE TView.Close;
  492.  
  493.     VAR
  494.         lastCommand:        TCommand;
  495.  
  496.     PROCEDURE CloseSubView(theSubView: TView);
  497.  
  498.         BEGIN
  499.         theSubView.Close;
  500.         END;
  501.  
  502.     BEGIN
  503.  
  504.     { ??? Seems like we should notify the world that we're closing instead of groping around for
  505.     stuff like the last command… }
  506.     lastCommand := GetLastCommand;
  507.     IF (lastCommand <> NIL) & (lastCommand.fView = SELF) THEN
  508.         CommitLastCommand;
  509.  
  510.     EachSubView(CloseSubView);
  511.     END;
  512.  
  513. {--------------------------------------------------------------------------------------------------}
  514. {$S MAViewRes}
  515.  
  516. PROCEDURE TView.ComputeSize(VAR newSize: VPoint);
  517.  
  518.     VAR
  519.         dimension:            VCoordinate;
  520.         vhs:                VHSelect;
  521.         minSize:            VPoint;
  522.  
  523.     BEGIN
  524.     CalcMinSize(minSize);
  525.  
  526.     { Adjust view size based on size determiners. }
  527.  
  528.     FOR vhs := v TO h DO
  529.         BEGIN
  530.         dimension := minSize.vh[vhs];                    { Set dimension to a default }
  531.         CASE fSizeDeterminer[vhs] OF
  532.             sizeVariable: ;                             { For sizeVariable dimension is already set
  533.                                                          correctly }
  534.             sizeFixed:
  535.                 dimension := fSize.vh[vhs];
  536.             sizeRelSuperView:
  537.                 dimension := newSize.vh[vhs];            { newSize set in SuperViewChangedSize }
  538.             sizeSuperView:
  539.                 IF fSuperview <> NIL THEN
  540.                     dimension := fSuperview.fSize.vh[vhs];
  541.             sizePage:
  542.             { If there is no printhandler we can defer until one is attached }
  543.                 IF fPrintHandler <> NIL THEN
  544.                     dimension := fPrintHandler.fViewPerPage.vh[vhs];
  545.             sizeFillPages:
  546.             { If there is no printhandler we can defer until one is attached }
  547.                 IF fPrintHandler <> NIL THEN
  548.                     dimension := Min(RoundUp(minSize.vh[vhs], fPrintHandler.fViewPerPage.vh[vhs]),
  549.                                      kMaxCoord);
  550.         END;
  551.         newSize.vh[vhs] := dimension;
  552.         END;
  553.     END;
  554.  
  555. {--------------------------------------------------------------------------------------------------}
  556. {$S MAViewRes}
  557.  
  558. FUNCTION TView.ContainsClipType(aType: ResType): BOOLEAN;
  559.  
  560.     VAR
  561.         offset:             LONGINT;
  562.  
  563.     BEGIN
  564.     ContainsClipType := (GetScrap(NIL, aType, offset) > 0)
  565.     END;
  566.  
  567. {--------------------------------------------------------------------------------------------------}
  568. {$S MAViewRes}
  569.  
  570. FUNCTION TView.ContainsMouse(theMouse: VPoint): BOOLEAN;
  571.  
  572.     VAR
  573.         extent:             VRect;
  574.  
  575.     BEGIN
  576.     GetExtent(extent);
  577.     ContainsMouse := isShown & PtInVRect(theMouse, extent);
  578.     END;
  579.  
  580. {--------------------------------------------------------------------------------------------------}
  581. {$S MAViewRes}
  582.  
  583. FUNCTION TView.CountSubViews: INTEGER;
  584.  
  585.     BEGIN
  586.     IF fSubViews <> NIL THEN
  587.         CountSubViews := fSubViews.GetSize
  588.     ELSE
  589.         CountSubViews := 0;
  590.     END;
  591.  
  592. {--------------------------------------------------------------------------------------------------}
  593. {$S MAViewRes}
  594.  
  595. FUNCTION TView.DoBreakFollowing(vhs: VHSelect;
  596.                                 prevBreak: VCoordinate;
  597.                                 VAR automatic: BOOLEAN): VCoordinate;
  598.  
  599.     BEGIN
  600.     DoBreakFollowing := fPrintHandler.BreakFollowing(vhs, prevBreak, automatic);
  601.     END;
  602.  
  603. {--------------------------------------------------------------------------------------------------}
  604. {$S MANonRes}
  605.  
  606. PROCEDURE TView.DoCalcPageStrips(VAR pageStrips: Point);
  607.  
  608.     BEGIN
  609.     fPrintHandler.CalcPageStrips(pageStrips);
  610.     END;
  611.  
  612. {--------------------------------------------------------------------------------------------------}
  613. {$S MANonRes}
  614. {$S MANonRes}
  615.  
  616. PROCEDURE TView.DoCalcViewPerPage(VAR viewPerPage: VPoint);
  617.  
  618.     BEGIN
  619.     viewPerPage := fSize;                                {in case fPrintHandler is vacuous}
  620.     fPrintHandler.CalcViewPerPage(viewPerPage);
  621.     END;
  622.  
  623. {--------------------------------------------------------------------------------------------------}
  624. {$S MAViewRes}
  625.  
  626. PROCEDURE TView.DoCheckPrinter;
  627.  
  628.     BEGIN
  629.     fPrintHandler.CheckPrinter
  630.     END;
  631.  
  632. {--------------------------------------------------------------------------------------------------}
  633. {$S MAViewRes}
  634.  
  635. PROCEDURE TView.DoChoice(origView: TView;
  636.                          itsChoice: INTEGER);
  637.  
  638.     BEGIN
  639.     IF fSuperview <> NIL THEN
  640.         fSuperview.DoChoice(origView, itsChoice)
  641.     ELSE
  642.         INHERITED DoChoice(origView, itsChoice);
  643.     END;
  644.  
  645. {--------------------------------------------------------------------------------------------------}
  646. {$S MAViewRes}
  647.  
  648. PROCEDURE TView.DoDrawPrintFeedback(area: Rect);
  649.  
  650.     BEGIN
  651.     IF qDebug THEN
  652.         AssumeFocused;
  653.  
  654.     IF fPrintHandler <> NIL THEN
  655.         fPrintHandler.DrawPrintFeedback(area);
  656.     END;
  657.  
  658. {--------------------------------------------------------------------------------------------------}
  659. {$S MAViewRes}
  660.  
  661. PROCEDURE TView.DoDrawPageBreak(vhs: VHSelect;
  662.                                 whichBreak: INTEGER;
  663.                                 loc: VCoordinate;
  664.                                 automatic: BOOLEAN);
  665.  
  666.     BEGIN
  667.     fPrintHandler.DrawPageBreak(vhs, whichBreak, loc, automatic);
  668.     END;
  669.  
  670. {--------------------------------------------------------------------------------------------------}
  671. {$S MAViewRes}
  672.  
  673. PROCEDURE TView.DoHighlightSelection(fromHL, toHL: HLState);
  674.  
  675.     BEGIN
  676.     END;
  677.  
  678. {--------------------------------------------------------------------------------------------------}
  679. {$S MASelCommand}
  680.  
  681. FUNCTION TView.DoMenuCommand(aCmdNumber: CmdNumber): TCommand;
  682.  
  683.     BEGIN
  684.     CASE aCmdNumber OF
  685.         cPrViewBase..cPrViewMax, cPrFileBase..cPrFileMax:
  686.             IF fPrintHandler <> NIL THEN
  687.                 DoMenuCommand := fPrintHandler.DoMenuCommand(aCmdNumber)
  688.             ELSE
  689.                 DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
  690.         OTHERWISE
  691.             DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
  692.     END;
  693.     END;
  694.  
  695. {--------------------------------------------------------------------------------------------------}
  696. {$S MASelCommand}
  697.  
  698. FUNCTION TView.DoMouseCommand(VAR theMouse: Point;
  699.                               VAR info: EventInfo;
  700.                               VAR hysteresis: Point): TCommand;
  701. { Its easy to get simple tracking that feeds back into your view.  Just create a command!
  702.     VAR
  703.         aCommand:    TNoChangesCommand;
  704.  
  705.     BEGIN
  706.     NEW(aCommand);
  707.     FailNIL(aCommand);
  708.     aCommand.INoChangesCommand(cNoCommand, fDocument, SELF, GetScroller(FALSE));
  709.     fTracksMouse := TRUE;
  710.     DoMouseCommand := aCommand;
  711.     END;
  712. }
  713.  
  714.     BEGIN
  715.     DoMouseCommand := NIL;
  716.     END;
  717.  
  718. {--------------------------------------------------------------------------------------------------}
  719. {$S MANonRes}
  720.  
  721. PROCEDURE TView.DoPagination;
  722.  
  723.     BEGIN
  724.     IF fPrintHandler <> NIL THEN
  725.         fPrintHandler.RedoPageBreaks
  726.     END;
  727.  
  728. {--------------------------------------------------------------------------------------------------}
  729. {$S MANonRes}
  730.  
  731. PROCEDURE TView.DoPrinterChanged;
  732.  
  733.     BEGIN
  734.     IF fPrintHandler <> NIL THEN
  735.         fPrintHandler.PrinterChanged;
  736.     END;
  737.  
  738. {--------------------------------------------------------------------------------------------------}
  739. {$S MAPrint}
  740.  
  741. PROCEDURE TView.DoSetPageOffset(coord: VPoint);
  742.  
  743.     BEGIN
  744.     fPrintHandler.SetPageOffset(coord);
  745.     END;
  746.  
  747. {--------------------------------------------------------------------------------------------------}
  748. {$S MAViewRes}
  749.  
  750. FUNCTION TView.DoSetCursor(localPoint: Point;
  751.                            cursorRgn: RgnHandle): BOOLEAN;
  752.  
  753.     BEGIN
  754.     { Our default is to claim the cursor as an arrow for the default cursor region. }
  755.     IF qDebug THEN
  756.         AssumeFocused;
  757.  
  758.     GetDefaultCursorRgn(localPoint, cursorRgn);
  759.     
  760.     SetCursor(arrow);
  761.     
  762.     DoSetCursor := TRUE;
  763.  
  764.     { If you claim the cursor don't forget to _PROPERLY_ calculate the cursorRgn or
  765.     WaitNextEvent might give you a lovely mouse-moved event shower. (Lather up!)
  766.  
  767.     P.S. In debug this is checked for in our original caller: TApplication.TrackMouse. }
  768.     END;
  769.  
  770. {--------------------------------------------------------------------------------------------------}
  771. {$S MAViewRes}
  772.  
  773. PROCEDURE TView.GetDefaultCursorRgn(localPoint: Point;
  774.                                        cursorRgn: RgnHandle);
  775.     CONST
  776.         kRgnHandleTooBig = 16*1024;                        { regions > 16K don't work too well, !!!
  777.                                                         move this to the interfaces soon... }
  778.  
  779.     VAR
  780.         r:                    Rect;
  781.         rgnHandleWasTooBig:    Boolean;
  782.  
  783.     PROCEDURE RemoveSubViewRgn(theSubView: TView);
  784.  
  785.         VAR
  786.             vFrame:             VRect;
  787.             frame:                Rect;
  788.  
  789.         BEGIN
  790.         IF NOT rgnHandleWasTooBig THEN
  791.             BEGIN
  792.             theSubView.GetFrame(vFrame);                    { Remember, the frame is in OUR coordinate
  793.                                                              system }
  794.             ViewToQDRect(vFrame, frame);
  795.             RectRgn(gTempRgn, frame);
  796.             DiffRgn(cursorRgn, gTempRgn, cursorRgn);        { Remove the subview from the claimed rgn }
  797.             
  798.             IF (GetHandleSize(Handle(cursorRgn)) > kRgnHandleTooBig) | (MemError <> NoErr) THEN
  799.                 BEGIN
  800.                 rgnHandleWasTooBig := TRUE;
  801.                 SetEmptyRgn(cursorRgn);
  802.                 END;
  803.             END;
  804.         END;
  805.  
  806.     BEGIN
  807.     { If we get all the way to this view without any other view having claimed the
  808.     cursor its because no superview handled it in a "HandleCursor" and no subview handled it
  809.     in a "DoSetCursor" thus there is a _very_ high probability that this view should set the cursor.
  810.     Just in case though, we remove the frames.
  811.  
  812.     If a containing view wishes to set the cursor for itself AND all its subview, the
  813.     place to do that is in our caller: HandleCursor.  See HandleCursor in the homebrew controls
  814.     TDialogView subclass in DemoDialogs.
  815.  
  816.     This strategy lets MacApp provide the _largest_ possible cursor rgn, as a default.    This way
  817.     windows, controls, background views, etc can have nice big cursor rgns but the developer can
  818.     wrest control if they care to. }
  819.  
  820.     IF qDebug THEN
  821.         AssumeFocused;
  822.  
  823.     GetQDExtent(r);
  824.     RectRgn(cursorRgn, r);
  825.  
  826.     {$IFC qDebug}
  827.     UseTempRgn('TView.GetDefaultCursorRgn, RemoveSubViewRgn');
  828.     {$EndC}
  829.  
  830.     rgnHandleWasTooBig := FALSE;
  831.     EachSubView(RemoveSubViewRgn);                    { We won't claim subview's territory }
  832.  
  833.     { Make sure the cursorpoint is _still_ included }
  834.     WITH localPoint DO
  835.         SetRectRgn(gTempRgn, h, v, h + 1, v + 1);
  836.     UnionRgn(gTempRgn, cursorRgn, cursorRgn);
  837.  
  838.     {$IFC qDebug}
  839.     DoneWithTempRgn;
  840.     {$ENDC}
  841.  
  842.     { If you claim the cursor don't forget to _PROPERLY_ calculate the cursorRgn or
  843.     WaitNextEvent might give you a lovely mouse-moved event shower. (Lather up!)
  844.  
  845.     P.S. In debug this is checked for in our original caller: TApplication.TrackMouse. }
  846.     END;
  847.  
  848. {--------------------------------------------------------------------------------------------------}
  849. {$S MAViewRes}
  850.  
  851. PROCEDURE TView.DoSetupMenus;
  852.  
  853.     BEGIN
  854.     INHERITED DoSetupMenus;
  855.  
  856.     IF fPrintHandler <> NIL THEN
  857.         fPrintHandler.DoSetupMenus;
  858.     END;
  859.  
  860. {--------------------------------------------------------------------------------------------------}
  861. {$S MAViewRes}
  862.  
  863. PROCEDURE TView.Draw(area: Rect);
  864.  
  865.     BEGIN
  866.     END;
  867.  
  868. {--------------------------------------------------------------------------------------------------}
  869. {$IFC qExperimentalAndUnsupported}
  870. {$S MAViewRes}
  871.  
  872. PROCEDURE TView.DoOffScreen(PROCEDURE WhatToDo);
  873. {$IFC qExperimentalAndUnsupported}
  874.  
  875.     TYPE
  876.         BitMapPtr = ^BitMap;
  877.  
  878.     VAR
  879.         visRect: Rect;
  880.         gblVisRect: Rect;
  881.  
  882.         cGrafPortPtr: CGrafPtr;
  883.         theGrafPort: GrafPtr;
  884.         Iscolor: BOOLEAN;
  885.  
  886.     PROCEDURE DoColor;
  887.  
  888.         VAR
  889.  
  890.             theBits: Handle;
  891.             mfBits: BOOLEAN; { true if theBits were allocated in MF Temp mem only needed for pre-
  892.             system 7.0 compatibility since in sys7 you can make mem mgr calls on MF memory. }
  893.             anErr: OSErr;
  894.             pm: PixMapHandle;
  895.             oldpm: PixMapHandle;
  896.             bmp: BitMapPtr;
  897.             pixmapsize: LONGINT;
  898.             rowsize: INTEGER;
  899.             tempCTab: CTabHandle;
  900.             theMaxDevice: GDHandle;
  901.             oldDevice: GDHandle;
  902.             pixelsize: INTEGER;
  903.             fi: FailInfo;
  904.  
  905.         PROCEDURE HdlDoColor(error: INTEGER; message: LONGINT);
  906.  
  907.             BEGIN
  908.             { Restore sanity }
  909.             SetPort(theGrafPort);
  910.             SetPortPix(oldpm);
  911.             SetGDevice(oldDevice);
  912.             IF theBits <> NIL THEN
  913.                 BEGIN
  914.                 IF mfBits THEN
  915.                     MFTempDisposHandle(theBits, anErr)
  916.                 ELSE
  917.                     theBits := DisposeIfHandle(theBits);
  918.                 END;
  919.             theBits := NIL;
  920.  
  921.             IF pm <> NIL THEN
  922.                 DisposPixMap(pm);
  923.  
  924.             END;
  925.  
  926.         BEGIN
  927.         theBits := NIL;
  928.         pm := NIL;
  929.         mfBits := FALSE;
  930.         oldpm := cGrafPortPtr^.portPixMap;
  931.  
  932.         { Determine the bit depth required for the drawing }
  933.         gblVisRect := visRect;
  934.         WITH gblVisRect DO
  935.             BEGIN
  936.             LocalToGlobal(topleft);
  937.             LocalToGlobal(botRight);
  938.             END;
  939.         theMaxDevice := GetMaxDevice(gblVisRect);
  940.         pixelsize := theMaxDevice^^.gdPMap^^.pixelsize;
  941.         {set the current device to the max device}
  942.         oldDevice := GetGDevice; {save theGDevice so we can restore it later}
  943.  
  944.         CatchFailures(fi, HdlDoColor);
  945.         SetGDevice(theMaxDevice); {Set to the maxdevice}
  946.  
  947.         IF gIntenseDebugging THEN
  948.             BEGIN
  949.             wrlblptr('  currentdevice', GetGDevice);
  950.             WRITELN;
  951.             END;
  952.  
  953.         pm := NewPixMap; {create the pix map (duplicate existing)}
  954.         IF pm = NIL THEN
  955.             SetGDevice(oldDevice)
  956.         ELSE
  957.             BEGIN
  958.             tempCTab := theMaxDevice^^.gdPMap^^.pmtable;
  959.             IF HandToHand(Handle(tempCTab)) <> NoErr THEN {duplicate old color table}
  960.                 BEGIN
  961.                 SetGDevice(oldDevice);
  962.                 DisposPixMap(pm);
  963.                 pm := NIL;
  964.                 END
  965.             ELSE
  966.                 BEGIN
  967.                 Handle(pm^^.pmtable) := DisposeIfHandle(pm^^.pmtable); { release the dummy ctab that
  968.                                                             NewPixMap allocates}
  969.                 pm^^.pmtable := tempCTab;
  970.  
  971.                 IF gIntenseDebugging THEN
  972.                     BEGIN
  973.                     WRITELN('  color quickdraw port');
  974.                     WrLblRect('  gblvisrect', gblVisRect);
  975.                     WRITELN;
  976.                     WRITELN('  pixel size = ', pixelsize);
  977.                     WrLblHexInt('  old rowbytes=', pm^^.rowbytes);
  978.                     WRITELN;
  979.                     END;
  980.  
  981.                 WITH visRect DO
  982.                     BEGIN
  983.                     rowsize := ((IntMultiply((right - left - 1), pixelsize) + 15) DIV 16) * 2;
  984.                     pixmapsize := IntMultiply(bottom - top, rowsize);
  985.                     END;
  986.  
  987.                 IF gConfiguration.hasTempMem THEN    { try drinking at the MultiFinder™ well first }
  988.                     BEGIN
  989.                     theBits := MFTempNewHandle(pixmapsize, anErr);
  990.                     IF (theBits <> NIL) & (gConfiguration.systemVersion < $700) THEN
  991.                         mfBits := TRUE;
  992.                     END;
  993.  
  994.                 IF theBits = NIL THEN    { couldn't get mfmem try in heap }
  995.                     theBits := NewPermHandle(pixmapsize);
  996.  
  997.                 IF gIntenseDebugging THEN
  998.                     WRITELN('  bit map size=', pixmapsize);
  999.  
  1000.                 IF theBits <> NIL THEN
  1001.                     BEGIN
  1002.                     pm^^.rowbytes := BOR(rowsize, $8000); {High bit is set to indicate that it is a pix
  1003.                                                            map}
  1004.                     pm^^.pixelsize := pixelsize;
  1005.     
  1006.                     IF mfBits THEN
  1007.                         MFTempHLock(theBits, anErr)
  1008.                     ELSE
  1009.                         LockHandleHigh(theBits);
  1010.  
  1011.                     pm^^.baseaddr := QDPtr(theBits^);
  1012.                     pm^^.bounds := visRect;
  1013.  
  1014.                     {Intercept the grafport's Pix map and use the offscreen map instead}
  1015.                     SetPortPix(pm);
  1016.  
  1017.                     EraseRect(visRect);
  1018.                     CopyBits(BitMapPtr(oldpm^)^, thePort^.portBits, visRect, visRect, srcOr, NIL);
  1019.                     END
  1020.                 ELSE
  1021.                     BEGIN
  1022.                     IF gIntenseDebugging THEN
  1023.                         BEGIN
  1024.                         WRITELN('could not allocate pixmap size=', pixmapsize);
  1025.                         END;
  1026.                     DisposPixMap(pm);
  1027.                     pm := NIL;
  1028.                     END;
  1029.                 END;
  1030.             END;
  1031.  
  1032.         WhatToDo;
  1033.  
  1034.         IF theBits <> NIL THEN
  1035.             BEGIN
  1036.         
  1037.             { What to do may have changed the focus }
  1038.             IF Focus THEN
  1039.                 BEGIN
  1040.                 IF gIntenseDebugging THEN
  1041.                     BEGIN
  1042.                     wrlblptr('  currentdevice', GetGDevice);
  1043.                     WRITELN;
  1044.                     END;
  1045.         
  1046.                 {restore the screen's pix map}
  1047.                 SetPortPix(oldpm);
  1048.                 bmp := BitMapPtr(pm^);
  1049.         
  1050.                 {restore the screen's device}
  1051.         
  1052.                 SetGDevice(oldDevice);
  1053.         
  1054.                 IF gIntenseDebugging THEN
  1055.                     BEGIN
  1056.                     WrLblHexInt('  rowbytes', bmp^.rowbytes);
  1057.                     WRITELN('  color copy');
  1058.                     END;
  1059.         
  1060.                 { blit back to the real screen }
  1061.                 CopyBits(bmp^, thePort^.portBits, visRect, visRect, srcCopy, NIL);
  1062.                 END
  1063.             ELSE IF qDebug THEN
  1064.                 ProgramBreak('in TView.DoOffScreen: Couldn''t regain focus');
  1065.         
  1066.             DisposPixMap(pm);
  1067.             pm := NIL;
  1068.  
  1069.             IF mfBits THEN
  1070.                 MFTempDisposHandle(theBits, anErr)
  1071.             ELSE
  1072.                 theBits := DisposeIfHandle(theBits);
  1073.             theBits := NIL;
  1074.         
  1075.             Success(fi);
  1076.             END;
  1077.         END;
  1078.  
  1079.     PROCEDURE DoBW;
  1080.  
  1081.         VAR
  1082.  
  1083.             theBits: Handle;
  1084.             mfBits: BOOLEAN; { true if theBits were allocated in MF Temp mem }
  1085.             anErr: OSErr;
  1086.             bm: BitMap;
  1087.             oldBits: BitMap;
  1088.             pm: PixMapHandle;
  1089.             bmp: BitMapPtr;
  1090.             rowsize: INTEGER;
  1091.             fi: FailInfo;
  1092.  
  1093.         PROCEDURE HdlDoBW(error: INTEGER; message: LONGINT);
  1094.  
  1095.             BEGIN
  1096.             { Restore law and order }
  1097.             SetPort(theGrafPort);
  1098.             SetPortBits(oldBits);
  1099.  
  1100.             IF theBits <> NIL THEN
  1101.                 BEGIN
  1102.                 IF mfBits THEN
  1103.                     MFTempDisposHandle(theBits, anErr)
  1104.                 ELSE
  1105.                     theBits := DisposeIfHandle(theBits);
  1106.                 END;
  1107.             theBits := NIL;
  1108.             END;
  1109.  
  1110.         BEGIN
  1111.         theBits := NIL;
  1112.         mfBits := FALSE;
  1113.         oldBits := thePort^.portBits; { Handy to have for failures too }
  1114.  
  1115.         CatchFailures(fi, HdlDoBW);
  1116.         IF gIntenseDebugging THEN
  1117.             WRITELN('  quickdraw port');
  1118.  
  1119.         WITH visRect DO
  1120.             BEGIN
  1121.             bm.rowbytes := (((right - left - 1) DIV 16) + 1) * 2;
  1122.             IF gConfiguration.hasTempMem THEN
  1123.                 BEGIN
  1124.                 theBits := MFTempNewHandle(IntMultiply(bottom - top, bm.rowbytes), anErr);
  1125.                 IF (theBits <> NIL) & (gConfiguration.systemVersion < $700) THEN
  1126.                     mfBits := TRUE;
  1127.                 END;
  1128.  
  1129.             IF theBits = NIL THEN
  1130.                 theBits := NewPermHandle(IntMultiply(bottom - top, bm.rowbytes));
  1131.             END;
  1132.  
  1133.         IF theBits <> NIL THEN
  1134.             BEGIN
  1135.             IF mfBits THEN
  1136.                 MFTempHLock(theBits, anErr)
  1137.             ELSE
  1138.                 LockHandleHigh(theBits);
  1139.  
  1140.             bm.baseaddr := QDPtr(theBits^);
  1141.             bm.bounds := visRect;
  1142.         
  1143.             IF gIntenseDebugging THEN
  1144.                 WRITELN('setting new port bits');
  1145.             SetPortBits(bm);
  1146.         
  1147.             EraseRect(visRect);
  1148.             CopyBits(oldBits, thePort^.portBits, visRect, visRect, srcOr, NIL);
  1149.         
  1150.             WhatToDo;
  1151.         
  1152.             { What to do may have changed the focus }
  1153.             IF Focus THEN
  1154.                 BEGIN
  1155.                 { blit back to the real screen }
  1156.                 SetPortBits(oldBits);
  1157.                 CopyBits(bm, thePort^.portBits, visRect, visRect, srcCopy, NIL);
  1158.                 END
  1159.             ELSE IF qDebug THEN
  1160.                 ProgramBreak('in TView.DoOffScreen: Couldn''t regain focus');
  1161.         
  1162.             IF mfBits THEN
  1163.                 MFTempDisposHandle(theBits, anErr)
  1164.             ELSE
  1165.                 theBits := DisposeIfHandle(theBits);
  1166.             theBits := NIL;
  1167.         
  1168.             Success(fi);
  1169.             END
  1170.         ELSE
  1171.             WhatToDo;
  1172.             
  1173.         END;
  1174.  
  1175.     BEGIN
  1176.     { An adaptation of Rob Hawley's excellent offscreen support.
  1177.     !!! Enhancements would include:
  1178.     • parameters to the WhatToDo procedure to give it control over blitting.
  1179.     • the ability to stay offscreen for extended periods and blit back periodically
  1180.         (this would be useful in scrolling).
  1181.     • the ability to defeat offscreening for views that have their own offscreen bitmaps
  1182.         already (ala DoubleVision)
  1183.     • the ability to disable software double-buffering if hardware double-buffering is
  1184.         available (say from a third party video-card)
  1185.     • controllable bit-depth (don't always need all 32 bits)
  1186.     }
  1187.     IF Focus THEN
  1188.         BEGIN
  1189.         GetVisibleRect(visRect);
  1190.         IF gIntenseDebugging THEN
  1191.             BEGIN
  1192.             WRITELN('TView.DoOffScreen');
  1193.             WrLblRect('  visrect', visRect);
  1194.             WRITELN;
  1195.             END;
  1196.  
  1197.         IF NOT EmptyRect(visRect) THEN
  1198.             BEGIN
  1199.  
  1200.             InsetRect(visRect, - 2, - 2); { A little extra space for good measure }
  1201.  
  1202.             theGrafPort := thePort;
  1203.             cGrafPortPtr := CGrafPtr(thePort);
  1204.             Iscolor := cGrafPortPtr^.portversion = $C000;
  1205.  
  1206.             IF gIntenseDebugging THEN
  1207.                 BEGIN
  1208.                 WrLblRect('  clipped visRect', visRect);
  1209.                 WRITELN;
  1210.                 WrLblRect('  update region', thePort^.visRgn^^.rgnbBox);
  1211.                 WRITELN;
  1212.                 WrLblHexInt('  cGrafPortPtr^.portversion', cGrafPortPtr^.portversion);
  1213.                 WRITELN;
  1214.                 END;
  1215.  
  1216.             IF Iscolor THEN
  1217.                 DoColor
  1218.             ELSE
  1219.                 DoBW;
  1220.             END;
  1221.         END;
  1222.  
  1223.     {$EndC}
  1224.     END;
  1225. {$EndC}
  1226.  
  1227. {--------------------------------------------------------------------------------------------------}
  1228. {$S MAViewRes}
  1229.  
  1230. PROCEDURE TView.DrawContents;
  1231.  
  1232.     VAR
  1233.         visRect:            Rect;
  1234.         aFocusRec:            FocusRec;
  1235.         displaying:         BOOLEAN;
  1236.         fi:                 FailInfo;
  1237.         {$IFC qExperimentalAndUnsupported}
  1238.         oldgEnableDoubleBuffering: BOOLEAN;
  1239.         {$EndC}
  1240.  
  1241.     PROCEDURE HdlDrawContents(error: OSErr;
  1242.                               message: LONGINT);
  1243.  
  1244.         BEGIN
  1245.         {$IFC qExperimentalAndUnsupported}
  1246.         gEnableDoubleBuffering := oldgEnableDoubleBuffering;
  1247.         {$ELSEC}
  1248.         IF aFocusRec.Clip <> NIL THEN
  1249.             DisposeRgn(aFocusRec.Clip);
  1250.         {$EndC}
  1251.         END;
  1252.  
  1253.     PROCEDURE DrawSubViewContents(theSubView: TView);
  1254.  
  1255.         VAR
  1256.             itsFrame:            VRect;
  1257.             itsQDFrame:         Rect;
  1258.  
  1259.         BEGIN
  1260.         IF theSubView.isShown THEN
  1261.             BEGIN
  1262.             {$IFC qExperimentalAndUnsupported}
  1263.             theSubView.DrawContents;
  1264.  
  1265.             {$ELSEC}
  1266.             { See if this subview is visible. Kinda yucko but still cheaper than Focus/IsVisible }
  1267.             theSubView.GetFrame(itsFrame);
  1268.             ViewToQDRect(itsFrame, itsQDFrame);
  1269.             IF RectInRgn(itsQDFrame, thePort^.clipRgn) | NOT displaying THEN
  1270.                 BEGIN
  1271.                 theSubView.DrawContents;
  1272.                 SetFocus(aFocusRec);                    { Restore my focus. }
  1273.                 END;
  1274.             {$EndC}
  1275.             END;
  1276.         END;
  1277.  
  1278.     PROCEDURE DoDrawContents;
  1279.  
  1280.         BEGIN
  1281.         IF Focus THEN
  1282.             BEGIN
  1283.             GetVisibleRect(visRect);
  1284.             displaying := NOT (gPrinting | gDrawingPictScrap);
  1285.             IF NOT EmptyRect(visRect) | NOT displaying THEN
  1286.                 BEGIN
  1287.                 Draw(visRect);
  1288.  
  1289.                 {$IFC qExperimentalAndUnsupported}
  1290.                 EachSubView(DrawSubViewContents);
  1291.  
  1292.                 {$ELSEC}
  1293.                 IF CountSubViews > 0 THEN
  1294.                     BEGIN
  1295.                     { Cobbler's kid shouldn't go barefoot.    We use our own stuff here now until the new
  1296.                     fast focusing is in. (post 2.0)
  1297.  
  1298.                     Focusing is currently (unfortunately) too expensive to do here.  So we save the
  1299.                     current focus so that it can be restored quickly.  Hopefully none of the subiew's
  1300.                     drawing will invalidate this saved focus or we're dead meat.  Well that's part of the
  1301.                     problem with the current focus save restore.
  1302.  
  1303.                     ??? Could get/set focus deal with chained focusrecs that can be invalidated by
  1304.                     invalidatefocus for safer usage.  Can most of this muck be avoided by fast focusing? }
  1305.                     CatchFailures(fi, HdlDrawContents);
  1306.                     aFocusRec.Clip := NIL;
  1307.                     aFocusRec.Clip := MakeNewRgn;
  1308.                     GetFocus(aFocusRec);                { Save the superview's focus (That's me). }
  1309.  
  1310.                     EachSubView(DrawSubViewContents);
  1311.                     Success(fi);
  1312.  
  1313.                     DisposeRgn(aFocusRec.Clip);
  1314.                     aFocusRec.Clip := NIL;
  1315.                     END;
  1316.                 {$EndC}
  1317.  
  1318.                 IF displaying THEN
  1319.                     BEGIN
  1320.  
  1321.                     {$IFC qExperimentalAndUnsupported}
  1322.                     IF Focus THEN;
  1323.                     {$EndC}
  1324.  
  1325.                     DoHighlightSelection(hlOff, fHLDesired);
  1326.                     IF fPrintHandler <> NIL THEN
  1327.                         DoDrawPrintFeedback(visRect);
  1328.                     END;
  1329.  
  1330.                 END;
  1331.             END;
  1332.         END;
  1333.  
  1334.     BEGIN
  1335.  
  1336.     {$IFC qExperimentalAndUnsupported}
  1337.     IF Focus & IsVisible THEN
  1338.         BEGIN
  1339.         IF gEnableDoubleBuffering & NOT (gPrinting | gDrawingPictScrap) THEN
  1340.             BEGIN
  1341.             oldgEnableDoubleBuffering := gEnableDoubleBuffering;
  1342.             gEnableDoubleBuffering := FALSE;            { so subviews won't attempt to do off screen
  1343.                                                          }
  1344.             CatchFailures(fi, HdlDrawContents);
  1345.             DoOffScreen(DoDrawContents);
  1346.             Success(fi);
  1347.             gEnableDoubleBuffering := oldgEnableDoubleBuffering;
  1348.             END
  1349.         ELSE
  1350.             DoDrawContents;
  1351.         END;
  1352.     {$ELSEC}
  1353.     DoDrawContents;
  1354.     {$EndC}
  1355.     END;
  1356.  
  1357. {--------------------------------------------------------------------------------------------------}
  1358. {$S MAViewRes}
  1359.  
  1360. PROCEDURE TView.EachSubView(PROCEDURE DoToSubView(theSubView: TView));
  1361.  
  1362.     BEGIN
  1363.     IF fSubViews <> NIL THEN
  1364.         fSubViews.Each(DoToSubView);
  1365.     END;
  1366.  
  1367. {--------------------------------------------------------------------------------------------------}
  1368. {$S MAViewRes}
  1369.  
  1370. FUNCTION TView.FindSubView(itsIdentifier: IDType): TView;
  1371.  
  1372.     VAR
  1373.         foundView:            TView;
  1374.         dummyView:            TView;
  1375.  
  1376.     FUNCTION TestSubID(theSubView: TView): BOOLEAN;
  1377.  
  1378.         BEGIN
  1379.         IF LONGINT(theSubView.fIdentifier) = LONGINT(itsIdentifier) THEN
  1380.             foundView := theSubView
  1381.         ELSE
  1382.             dummyView := theSubView.FirstSubViewThat(TestSubID);
  1383.         TestSubID := foundView <> NIL;
  1384.         END;
  1385.  
  1386.     BEGIN
  1387.     IF LONGINT(fIdentifier) = LONGINT(itsIdentifier) THEN
  1388.         foundView := SELF
  1389.     ELSE
  1390.         BEGIN
  1391.         foundView := NIL;
  1392.         dummyView := FirstSubViewThat(TestSubID);
  1393.         END;
  1394.     {$IFC qDebug}
  1395.     IF foundView = NIL THEN
  1396.         BEGIN
  1397.         WRITELN('Unable to find subview: ''', itsIdentifier, '''');
  1398.         IF gIntenseDebugging THEN
  1399.             ProgramBreak('!');
  1400.         END;
  1401.     {$ENDC}
  1402.     FindSubView := foundView;
  1403.     END;
  1404.  
  1405. {--------------------------------------------------------------------------------------------------}
  1406. {$S MAViewRes}
  1407.  
  1408. FUNCTION TView.FirstSubViewThat(FUNCTION TestSubView(theSubView: TView): BOOLEAN): TView;
  1409.  
  1410.     BEGIN
  1411.     {$Push} {$R-}                                        { Look, its ok to type coerce a nil
  1412.                                                          reference but the world gets really crazy
  1413.                                                          if the TestSubView function (or something)
  1414.                                                          frees the view that is returned. That's
  1415.                                                          why we defeat the run-time coercion
  1416.                                                          testing that is done if range checking is
  1417.                                                          true. }
  1418.     IF fSubViews <> NIL THEN
  1419.         FirstSubViewThat := TView(fSubViews.FirstThat(TestSubView))
  1420.     ELSE
  1421.         FirstSubViewThat := NIL;
  1422.     {$Pop}
  1423.     END;
  1424.  
  1425. {--------------------------------------------------------------------------------------------------}
  1426. {$S MAViewRes}
  1427.  
  1428. FUNCTION TView.Focus: BOOLEAN;
  1429.  
  1430.     CONST
  1431.         kMaxOriginFixup     = 1024;                     { The maximum amout by which to _fixup_ (not
  1432.                                                          offset) the QD origin when focusing. This
  1433.                                                          allows patterns and pixpats to be pinned
  1434.                                                          to global space as they were intended. See
  1435.                                                          note below. Larger values than this may be
  1436.                                                          required for _extremely_ complex pixpats
  1437.                                                          (not patterns as they are restricted to 8
  1438.                                                          bit repetition.) The reason that the fixup
  1439.                                                          is restricted is that you don't want to
  1440.                                                          run off the end of QD space and we already
  1441.                                                          have slop allowance of about 2k in
  1442.                                                          ViewCoords.p. Good Luck Jim! (??? should
  1443.                                                          this be settable for the adventurous?) }
  1444.  
  1445.     VAR
  1446.         tempLongOffset:     VCoordinate;
  1447.         relOrigin:            VPoint;
  1448.         qdFrame:            Rect;
  1449.         aRect:                Rect;
  1450.         viewRect:            VRect;
  1451.         visRect:            VRect;
  1452.         myFrame:            VRect;
  1453.         vhs:                VHSelect;
  1454.         {$IFC qDebug}
  1455.         currentPort:        GrafPtr;
  1456.         {$ENDC}
  1457.         {$IFC qExperimentalAndUnsupported}
  1458.         aFocusRec:            FocusRec;
  1459.         {$ENDC}
  1460.  
  1461.         
  1462.     { thanks kaar! (memorial hack)
  1463.     The problems with pattern alignment when using 32bit views occured when virtual
  1464.     origin of the port no longer had coordinates that were multiples of 8. This
  1465.     could occur if, for example, one scrolled a view by increments of other than 8,
  1466.     16, or other multiple of 8.
  1467.  
  1468.     The reason for this was due to the way the origin of the port was handled for
  1469.     large views. In large views, the origin is always set to (0, 0), and the origin
  1470.     is maintained in gLongOffset. When this happens, patterns are always draw as if
  1471.     we are always scrolled to the extreme top and left of our view. However, this
  1472.     is not always true. It could be that we are actually scrolled right or down 1
  1473.     pixel. In this case, our coordinates are correctly transformed by ViewToQDPt,
  1474.     but QuickDraw doesn't know anything about gLongOffset, so it still draws
  1475.     patterns thinking that we are at (0, 0), instead of (1, 1).
  1476.  
  1477.     The solution was to appropriately set the origin so that patterns are drawn
  1478.     correctly aligned. This can be done by making sure that we set the origin to
  1479.     some value that will cause QuickDraw to perform in exactly the same way as if
  1480.     the origin were really at the value specified by gLongOffset. Since classic
  1481.     QuickDraw patterns repeat after 8 pixels, we can accomplish this task by making
  1482.     sure that gLongOffset is a multiple of 8, and setting the origin to compensate
  1483.     by setting it to gLongOffset MOD 8.
  1484.  
  1485.     Unfortunately, this will only work for classic QuickDraw pattersn that repeat
  1486.     after 8 pixels. With PixPats, this period can be any power of 2. In order to
  1487.     support them, we have to make sure that gLongOffset must be only a multiple of
  1488.     whatever power of 2 is being used. Ideally, therefore, we could like to make
  1489.     the chunkiness of gLongOffset to be as large as possible. On the other hand, we
  1490.     can make it too large, or else the amount by which we offset the origin in
  1491.     TView.Focus may overflow QuickDraw's limits. I think that a value of 1024 or
  1492.     2048 should be sufficient enough to accomodate the largest of PixPats a
  1493.     developer may use, and still be small enough that we shouldn't overflow
  1494.     QuickDraw.
  1495.     }
  1496.  
  1497.     BEGIN
  1498.     Focus := TRUE;
  1499.  
  1500.     IF IsFocused THEN
  1501.         BEGIN
  1502.         {$IFC qDebug}
  1503.         GetPort(currentPort);
  1504.         IF GetGrafPort <> currentPort THEN
  1505.             ProgramBreak('TView.Focus: Port is incorrect');
  1506.         {$ENDC}
  1507.         Exit(Focus);
  1508.         END;
  1509.  
  1510.     {$IFC qExperimentalAndUnsupported}
  1511.     IF fFocusRec.IsValid THEN
  1512.         BEGIN
  1513.         aFocusRec := fFocusRec;
  1514.         SetFocus(aFocusRec);
  1515.         Exit(Focus);
  1516.         END;
  1517.     {$EndC}
  1518.  
  1519.     IF (gDrawingPictScrapView = SELF) | ((gCurrPrintHandler <> NIL) & (gCurrPrintHandler.fView =
  1520.        SELF)) THEN
  1521.         BEGIN
  1522.         { GrafPort has been supplied }
  1523.         gFocusedView := SELF;
  1524.         END
  1525.  
  1526.     ELSE IF FocusOnSuperView THEN
  1527.         BEGIN
  1528.         gFocusedView := SELF;                            { If I can focus on a superview then by
  1529.                                                          definition I can focus on myself }
  1530.         GetFrame(myFrame);                                {!!! We do this enough. Really need a
  1531.                                                          GetQDFrame }
  1532.         ViewToQDRect(myFrame, qdFrame);                 {Must be done before changing gLongOffset
  1533.                                                          Really want to do the line below but it's
  1534.                                                          late and viewEdit is getting cranky… Next
  1535.                                                          release, really. }
  1536.         { NOPE fSuperView.ViewToQDRect(myFrame, qdFrame);} { Must be done while focused on superview
  1537.                                                             }
  1538.  
  1539.         FOR vhs := v TO h DO
  1540.             IF fSize.vh[vhs] > kMaxCoord THEN
  1541.                 BEGIN
  1542.                 tempLongOffset := gLongOffset.vh[vhs] - fLocation.vh[vhs];
  1543.                 relOrigin.vh[vhs] := tempLongOffset MOD kMaxOriginFixup;
  1544.                 gLongOffset.vh[vhs] := tempLongOffset - relOrigin.vh[vhs];
  1545.                 END
  1546.             ELSE
  1547.                 BEGIN
  1548.                 relOrigin.vh[vhs] := gLongOffset.vh[vhs] - fLocation.vh[vhs];
  1549.                 gLongOffset.vh[vhs] := 0;
  1550.                 END;
  1551.  
  1552.         WITH thePort^.portRect, relOrigin DO
  1553.             BEGIN
  1554.             SetOrigin(left + h, top + v);
  1555.             ClipFurtherTo(qdFrame, h, v);
  1556.             END;
  1557.  
  1558.         {$IFC qExperimentalAndUnsupported}
  1559.         aFocusRec.clip := fFocusRec.clip;
  1560.         GetFocus(aFocusRec);
  1561.         fFocusRec := aFocusRec;
  1562.         {$EndC}
  1563.         END
  1564.     ELSE
  1565.         BEGIN
  1566.         { If we get this far, then we can't focus }
  1567.         ClipRect(gZeroRect);
  1568.         InvalidateFocus;
  1569.         Focus := FALSE;
  1570.         END;
  1571.     END;
  1572.  
  1573. {--------------------------------------------------------------------------------------------------}
  1574. {$S MAViewRes}
  1575.  
  1576. FUNCTION TView.FocusOnSuperView: BOOLEAN;
  1577.  
  1578.     BEGIN
  1579.     IF gDrawingPictScrap | gPrinting THEN
  1580.         FocusOnSuperView := TRUE
  1581.     ELSE IF fSuperview <> NIL THEN
  1582.         FocusOnSuperView := fSuperview.Focus
  1583.     ELSE
  1584.         FocusOnSuperView := FALSE;
  1585.     END;
  1586.  
  1587. {--------------------------------------------------------------------------------------------------}
  1588. {$S MAViewRes}
  1589.  
  1590. PROCEDURE TView.ForceRedraw;
  1591.  
  1592.     VAR
  1593.         extent:             VRect;
  1594.  
  1595.     BEGIN
  1596.     GetExtent(extent);
  1597.     InvalidVRect(extent);
  1598.     END;
  1599.  
  1600. {--------------------------------------------------------------------------------------------------}
  1601. {$S MAClipboard}
  1602.  
  1603. PROCEDURE TView.FreeFromClipboard;
  1604.  
  1605.     BEGIN
  1606.     IF fDocument <> NIL THEN
  1607.         fDocument.FreeFromClipboard
  1608.     ELSE
  1609.         Free;
  1610.     END;
  1611.  
  1612. {--------------------------------------------------------------------------------------------------}
  1613. {$S MAInspector}
  1614.  
  1615. PROCEDURE TView.GetInspectorName(VAR inspectorName: Str255); OVERRIDE;
  1616.  
  1617.     VAR
  1618.         itsWindow:            TWindow;
  1619.  
  1620.     BEGIN
  1621.     IF (fSuperview <> NIL) & IsObject(fSuperview) THEN
  1622.         BEGIN
  1623.         itsWindow := GetWindow;
  1624.         IF (itsWindow <> NIL) & IsObject(itsWindow) & (NOT ODD(ORD4(itsWindow.fWMgrWindow))) THEN
  1625.             BEGIN
  1626.             itsWindow.GetTitle(inspectorName);
  1627.             inspectorName := CONCAT('In ', inspectorName);
  1628.             END;
  1629.         END;
  1630.     END;
  1631.  
  1632. {--------------------------------------------------------------------------------------------------}
  1633. {$S MAViewRes}
  1634.  
  1635. FUNCTION TView.IsFocused: BOOLEAN;
  1636.  
  1637.     BEGIN
  1638.     IsFocused := gFocusedView = SELF;
  1639.     END;
  1640.  
  1641. {--------------------------------------------------------------------------------------------------}
  1642. {$S MAViewRes}
  1643.  
  1644. FUNCTION TView.GetDialogView: TView;
  1645.  
  1646.     BEGIN
  1647.     IF fSuperview <> NIL THEN
  1648.         GetDialogView := fSuperview.GetDialogView
  1649.     ELSE
  1650.         GetDialogView := NIL;
  1651.     END;
  1652.  
  1653. {--------------------------------------------------------------------------------------------------}
  1654. {$S MAViewRes}
  1655.  
  1656. PROCEDURE TView.GetExtent(VAR itsExtent: VRect);
  1657.  
  1658.     BEGIN
  1659.     WITH itsExtent DO
  1660.         BEGIN
  1661.         topleft := gZeroVPt;
  1662.         botRight := fSize;
  1663.         END;
  1664.     END;
  1665.  
  1666. {--------------------------------------------------------------------------------------------------}
  1667. {$S MAViewRes}
  1668.  
  1669. PROCEDURE TView.GetFrame(VAR itsFrame: VRect);
  1670.  
  1671.     BEGIN
  1672.     WITH itsFrame DO
  1673.         BEGIN
  1674.         topleft := fLocation;
  1675.         botRight := topleft;
  1676.         {$Push} {$H-}
  1677.         AddVPt(fSize, botRight);
  1678.         {$Pop}
  1679.         END;
  1680.     END;
  1681.  
  1682. {--------------------------------------------------------------------------------------------------}
  1683. {$S MAViewRes}
  1684.  
  1685. FUNCTION TView.GetGrafPort: GrafPtr;
  1686.  
  1687.     BEGIN
  1688.     IF gPrinting | gDrawingPictScrap THEN
  1689.         GetGrafPort := thePort                            {thePort assumed to be set by print handler}
  1690.     ELSE IF fSuperview <> NIL THEN
  1691.         GetGrafPort := fSuperview.GetGrafPort
  1692.     ELSE
  1693.         GetGrafPort := NIL;
  1694.     END;
  1695.  
  1696. {--------------------------------------------------------------------------------------------------}
  1697. {$S MANonRes}
  1698.  
  1699. PROCEDURE TView.GetPrintExtent(VAR printExtent: VRect);
  1700.  
  1701.     BEGIN
  1702.     GetExtent(printExtent);
  1703.     END;
  1704.  
  1705. {--------------------------------------------------------------------------------------------------}
  1706. {$S MAViewRes}
  1707.  
  1708. PROCEDURE TView.GetQDExtent(VAR qdExtent: Rect);
  1709.  
  1710.     VAR
  1711.         vr:                 VRect;
  1712.  
  1713.     BEGIN
  1714.     GetExtent(vr);
  1715.     ViewToQDRect(vr, qdExtent);
  1716.     END;
  1717.  
  1718. {--------------------------------------------------------------------------------------------------}
  1719. {$S MAViewRes}
  1720.  
  1721. FUNCTION TView.GetScroller(immediateSuperView: BOOLEAN): TScroller;
  1722.  
  1723.     VAR
  1724.         aScroller:            TScroller;
  1725.  
  1726.     BEGIN
  1727.     GetScroller := NIL;
  1728.     IF fSuperview <> NIL THEN
  1729.         BEGIN
  1730.         aScroller := fSuperview.GetScroller(immediateSuperView);
  1731.         IF (aScroller = fSuperview) | (NOT immediateSuperView) THEN
  1732.             GetScroller := aScroller;
  1733.         END;
  1734.     END;
  1735.  
  1736. {--------------------------------------------------------------------------------------------------}
  1737. {$S MAViewRes}
  1738.  
  1739. PROCEDURE TView.GetVisibleRect(VAR visQDRect: Rect);
  1740.  
  1741.     BEGIN
  1742.     GetQDExtent(visQDRect);
  1743.     VisibleRect(visQDRect);
  1744.     END;
  1745.  
  1746. {--------------------------------------------------------------------------------------------------}
  1747. {$S MAViewRes}
  1748.  
  1749. FUNCTION TView.GetWindow: TWindow;
  1750.  
  1751.     BEGIN
  1752.     IF fSuperview <> NIL THEN
  1753.         GetWindow := fSuperview.GetWindow
  1754.     ELSE
  1755.         GetWindow := NIL;
  1756.     END;
  1757.  
  1758. {--------------------------------------------------------------------------------------------------}
  1759. {$S MAClipboard}
  1760.  
  1761. FUNCTION TView.GivePasteData(aDataHandle: Handle;
  1762.                              dataType: ResType): LONGINT;
  1763.  
  1764.     VAR
  1765.         offset:             LONGINT;
  1766.         err:                LONGINT;
  1767.         savedPerm:            BOOLEAN;
  1768.  
  1769.     BEGIN
  1770.  {Make sure the scrap handle is grown out of permanent memory.    If it
  1771.   was grown out of temporary memory it would eat away at our
  1772.   code space.}
  1773.     savedPerm := PermAllocation(TRUE);
  1774.     err := GetScrap(aDataHandle, dataType, offset);
  1775.     savedPerm := PermAllocation(savedPerm);
  1776.  
  1777.     {$IFC qDebug}
  1778.     IF err < 0 THEN
  1779.         WRITELN('TView.GivePasteData got error code # ', err: 1, ' from GetScrap for type "',
  1780.                 dataType, '"');
  1781.     {$ENDC}
  1782.     GivePasteData := err;
  1783.     END;
  1784.  
  1785. {--------------------------------------------------------------------------------------------------}
  1786. {$S MAViewRes}
  1787.  
  1788. FUNCTION TView.HandleCursor(theMouse: VPoint;
  1789.                             cursorRgn: RgnHandle): TView;
  1790.  
  1791.     VAR
  1792.         dummyView, viewThatHandledCursor: TView;
  1793.  
  1794.     FUNCTION TestMouse(theSubView: TView): BOOLEAN;
  1795.  
  1796.         VAR
  1797.             subViewPt:            VPoint;
  1798.  
  1799.         BEGIN
  1800.         subViewPt := theMouse;
  1801.         theSubView.SuperToLocal(subViewPt);
  1802.         
  1803.         { don't give views on the clipboard a shot at claiming the cursor
  1804.         !!! need a better way to control which views get to claim the cursor 
  1805.         don't need to test in DoSetCursor whether the view is the gClipView }
  1806.         IF theSubView.ContainsMouse(subViewPt) & (theSubView <> gClipView) THEN
  1807.             viewThatHandledCursor := theSubView.HandleCursor(subViewPt, cursorRgn);
  1808.             
  1809.         TestMouse := viewThatHandledCursor <> NIL;
  1810.         END;
  1811.  
  1812.     BEGIN
  1813.     {Assume if we got here then we already know the mouse is in this view}
  1814.     viewThatHandledCursor := NIL;
  1815.     dummyView := LastSubViewThat(TestMouse);
  1816.  
  1817.     IF (viewThatHandledCursor = NIL) & (SELF <> gClipView) THEN
  1818.         IF IsViewEnabled & Focus & DoSetCursor(ViewToQDPt(theMouse), cursorRgn) THEN
  1819.             BEGIN
  1820.             if qDebug & NOT EmptyRgn(cursorRgn) & NOT PtInRgn(ViewToQDPt(theMouse), cursorRgn) THEN
  1821.                 BEGIN
  1822.                 ProgramBreak('Mouse not in the cursor region when the cursor rgn is claimed');
  1823.                 WrLblVPt('local cursor', theMouse);
  1824.                 WrLblRect('  cursorRgn^^.rgnBBox', cursorRgn^^.rgnBBox);
  1825.                 END;
  1826.                 
  1827.             viewThatHandledCursor := SELF;
  1828.             END;
  1829.  
  1830.     HandleCursor := viewThatHandledCursor;
  1831.     END;
  1832.  
  1833. {--------------------------------------------------------------------------------------------------}
  1834. {$S MASelCommand}
  1835.  
  1836. FUNCTION TView.HandleMouseDown(theMouse: VPoint;
  1837.                                VAR info: EventInfo;
  1838.                                VAR hysteresis: Point;
  1839.                                VAR theCommand: TCommand): BOOLEAN;
  1840.  
  1841.     VAR
  1842.         viewThatHandledMouse: TView;
  1843.         theQDMouse:         Point;
  1844.  
  1845.     FUNCTION TestMouse(theSubView: TView): BOOLEAN;
  1846.  
  1847.         VAR
  1848.             subViewPt:            VPoint;
  1849.  
  1850.         BEGIN
  1851.         subViewPt := theMouse;
  1852.         theSubView.SuperToLocal(subViewPt);
  1853.         IF theSubView.ContainsMouse(subViewPt) THEN
  1854.             TestMouse := theSubView.HandleMouseDown(subViewPt, info, hysteresis, theCommand)
  1855.         ELSE
  1856.             TestMouse := FALSE;
  1857.         END;
  1858.  
  1859.     BEGIN
  1860.     HandleMouseDown := FALSE;
  1861.     theCommand := NIL;
  1862.  
  1863.     {Assume if we got here then we already know the mouse is in this view}
  1864.  
  1865.     viewThatHandledMouse := LastSubViewThat(TestMouse);
  1866.  
  1867.     IF viewThatHandledMouse <> NIL THEN                 {a subview handled it}
  1868.         HandleMouseDown := TRUE
  1869.     ELSE IF IsViewEnabled & Focus THEN                    {see if we can handle it}
  1870.         BEGIN
  1871.         theQDMouse := ViewToQDPt(theMouse);
  1872.         theCommand := DoMouseCommand(theQDMouse, info, hysteresis);
  1873.         HandleMouseDown := TRUE;
  1874.         END;
  1875.     END;
  1876.  
  1877. {--------------------------------------------------------------------------------------------------}
  1878. {$S MAViewRes}
  1879.  
  1880. FUNCTION TView.HasPendingUpdate: BOOLEAN;
  1881.  
  1882.     BEGIN
  1883.     IF fSuperview <> NIL THEN
  1884.         HasPendingUpdate := fSuperview.HasPendingUpdate
  1885.     ELSE
  1886.         HasPendingUpdate := FALSE;
  1887.     END;
  1888.  
  1889. {--------------------------------------------------------------------------------------------------}
  1890. {$S MAViewRes}
  1891.  
  1892. PROCEDURE TView.InvalidRect(r: Rect);
  1893.  
  1894.     BEGIN
  1895.     IF Focus THEN
  1896.         BEGIN
  1897.         VisibleRect(r);
  1898.         InvalRect(r);
  1899.         END;
  1900.     END;
  1901.  
  1902. {--------------------------------------------------------------------------------------------------}
  1903. {$S MAViewRes}
  1904.  
  1905. PROCEDURE TView.InvalidVRect(viewRect: VRect);
  1906.  
  1907.     VAR
  1908.         r:                    Rect;
  1909.  
  1910.     BEGIN
  1911.     IF Focus THEN
  1912.         BEGIN
  1913.         ViewToQDRect(viewRect, r);
  1914.         InvalidRect(r);
  1915.         END;
  1916.     END;
  1917.  
  1918. {--------------------------------------------------------------------------------------------------}
  1919. {$S MAViewRes}
  1920.  
  1921. PROCEDURE TView.InvalidateFocus;
  1922.  
  1923.     PROCEDURE InvalidateAFocus(theView: TView);
  1924.  
  1925.         BEGIN
  1926.         theView.InvalidateFocus;
  1927.         END;
  1928.  
  1929.     BEGIN
  1930.  
  1931.     {$IFC qExperimentalAndUnsupported}
  1932.     { !!! no focus caching in this release. (2.0) }
  1933.     fFocusRec.IsValid := FALSE;
  1934.     SetEmptyRgn(fFocusRec.Clip);
  1935.     {$EndC}
  1936.  
  1937.     EachSubView(InvalidateAFocus);
  1938.  
  1939.     IF gfocusedview <> NIL THEN
  1940.         BEGIN
  1941.         IF gfocusedview = self THEN
  1942.             gfocusedview := NIL;
  1943.         END;
  1944.     END;
  1945.  
  1946. {--------------------------------------------------------------------------------------------------}
  1947. {$S MAViewRes}
  1948.  
  1949. FUNCTION TView.isShown: BOOLEAN;
  1950.  
  1951.     BEGIN
  1952.     isShown := fShown;                                    {??? Shouldn't we ask our superview? }
  1953.     END;
  1954.  
  1955. {--------------------------------------------------------------------------------------------------}
  1956. {$S MAViewRes}
  1957.  
  1958. FUNCTION TView.IsViewEnabled: BOOLEAN;
  1959.  
  1960.     BEGIN
  1961.     IsViewEnabled := fViewEnabled;
  1962.     END;
  1963.  
  1964. {--------------------------------------------------------------------------------------------------}
  1965. {$S MAViewRes}
  1966.  
  1967. FUNCTION TView.IsVisible: BOOLEAN;
  1968.  
  1969.     BEGIN
  1970.     {$IFC qDebug}
  1971.     AssumeFocused;
  1972.     {$EndC}
  1973.  
  1974.     IsVisible := isShown & NOT EmptyRgn(thePort^.clipRgn);
  1975.     END;
  1976.  
  1977. {--------------------------------------------------------------------------------------------------}
  1978. {$S MAViewRes}
  1979.  
  1980. FUNCTION TView.LastSubViewThat(FUNCTION TestSubView(theSubView: TView): BOOLEAN): TView;
  1981.  
  1982.     BEGIN
  1983.     {$Push} {$R-}                                        { Look, its ok to type coerce a nil
  1984.                                                          reference but the world gets really crazy
  1985.                                                          if the TestSubView function (or something)
  1986.                                                          frees the view that is returned. That's
  1987.                                                          why we defeat the run-time coercion
  1988.                                                          testing that is done if range checking is
  1989.                                                          true. }
  1990.     IF fSubViews <> NIL THEN
  1991.         LastSubViewThat := TView(fSubViews.LastThat(TestSubView))
  1992.     ELSE
  1993.         LastSubViewThat := NIL;
  1994.     {$Pop}
  1995.     END;
  1996.  
  1997. {--------------------------------------------------------------------------------------------------}
  1998. {$S MAViewRes}
  1999.  
  2000. PROCEDURE TView.LocalToSuper(VAR thePoint: VPoint);
  2001.  
  2002.     BEGIN
  2003.     {$Push} {$H-}
  2004.     AddVPt(fLocation, thePoint);
  2005.     {$Pop}
  2006.     END;
  2007.  
  2008. {--------------------------------------------------------------------------------------------------}
  2009. {$S MAViewRes}
  2010.  
  2011. PROCEDURE TView.LocalToWindow(VAR thePoint: VPoint);
  2012.  
  2013.     BEGIN
  2014.     IF fSuperview <> NIL THEN
  2015.         BEGIN
  2016.         LocalToSuper(thePoint);
  2017.         fSuperview.LocalToWindow(thePoint);
  2018.         END;
  2019.     END;
  2020.  
  2021. {--------------------------------------------------------------------------------------------------}
  2022. {$S MANonRes}
  2023.  
  2024. PROCEDURE TView.Locate(h, v: VCoordinate;
  2025.                        invalidate: BOOLEAN);
  2026.  
  2027.     PROCEDURE NotifySubView(theSubView: TView);
  2028.  
  2029.         BEGIN
  2030.         theSubView.SuperViewMoved(invalidate);
  2031.         END;
  2032.  
  2033.     BEGIN
  2034.     IF (h <> fLocation.h) | (v <> fLocation.v) THEN
  2035.         BEGIN
  2036.         IF invalidate THEN
  2037.             ForceRedraw;
  2038.         fLocation.h := h;
  2039.         fLocation.v := v;
  2040.         InvalidateFocus;                                {Must re-focus because view moved.}
  2041.         gApplication.InvalidateCursorRgn;                {Must re-calc cursor rgn.}
  2042.         IF invalidate THEN
  2043.             ForceRedraw;
  2044.  
  2045.         IF fSuperview <> NIL THEN
  2046.             fSuperview.SubViewMoved(SELF);
  2047.         EachSubView(NotifySubView);
  2048.         END;
  2049.     END;
  2050.  
  2051. {--------------------------------------------------------------------------------------------------}
  2052. {$S MANonRes}
  2053.  
  2054. PROCEDURE TView.MakeFirstSubView(theSubView: TView);
  2055.  
  2056.     BEGIN
  2057.     IF fSubViews <> NIL THEN                            {there must be at least one subview}
  2058.         IF TView(fSubViews.First) <> theSubView THEN
  2059.             BEGIN
  2060.             fSubViews.Delete(theSubView);
  2061.             fSubViews.InsertFirst(theSubView);
  2062.             theSubView.ForceRedraw;
  2063.             END;
  2064.     END;
  2065.  
  2066. {--------------------------------------------------------------------------------------------------}
  2067. {$S MANonRes}
  2068.  
  2069. PROCEDURE TView.MakeLastSubView(theSubView: TView);
  2070.  
  2071.     BEGIN
  2072.     IF fSubViews <> NIL THEN                            {there must be at least one subview}
  2073.         IF TView(fSubViews.Last) <> theSubView THEN
  2074.             BEGIN
  2075.             fSubViews.Delete(theSubView);
  2076.             fSubViews.InsertLast(theSubView);
  2077.             theSubView.ForceRedraw;
  2078.             END;
  2079.     END;
  2080.  
  2081. {--------------------------------------------------------------------------------------------------}
  2082. {$S MAOpen}
  2083.  
  2084. PROCEDURE TView.Open;
  2085.  
  2086.     PROCEDURE OpenSubView(theSubView: TView);
  2087.  
  2088.         BEGIN
  2089.         theSubView.Open;
  2090.         END;
  2091.  
  2092.     BEGIN
  2093.     EachSubView(OpenSubView);
  2094.     END;
  2095.  
  2096. {--------------------------------------------------------------------------------------------------}
  2097. {$S MANonRes}
  2098.  
  2099. PROCEDURE TView.PageInteriorChanged(newInterior: Rect);
  2100.  
  2101.     BEGIN
  2102.     END;
  2103.  
  2104. {--------------------------------------------------------------------------------------------------}
  2105. {$S MAViewRes}
  2106.  
  2107. PROCEDURE TView.QDToViewPt(qdPoint: Point;
  2108.                            VAR viewPt: VPoint);
  2109.  
  2110.     BEGIN
  2111.     {$IFC qDebug}
  2112.     AssumeFocused;
  2113.     {$ENDC}
  2114.  
  2115.     PtToVPt(qdPoint, viewPt);
  2116.     AddVPt(gLongOffset, viewPt);
  2117.     END;
  2118.  
  2119. {--------------------------------------------------------------------------------------------------}
  2120. {$S MAViewRes}
  2121.  
  2122. PROCEDURE TView.QDToViewRect(qdRect: Rect;
  2123.                              VAR viewRect: VRect);
  2124.  
  2125.     BEGIN
  2126.     {$IFC qDebug}
  2127.     AssumeFocused;
  2128.     {$ENDC}
  2129.  
  2130.     RectToVRect(qdRect, viewRect);
  2131.     OffsetVRect(viewRect, gLongOffset.h, gLongOffset.v);
  2132.     END;
  2133.  
  2134. {--------------------------------------------------------------------------------------------------}
  2135. {$S MANonRes}
  2136.  
  2137. PROCEDURE TView.RemoveSubView(theSubView: TView);
  2138.  
  2139.     VAR
  2140.         itsWindow:            TWindow;
  2141.  
  2142.     BEGIN
  2143.     IF qDebug THEN
  2144.         FailNonObject(theSubView);
  2145.  
  2146.     IF fSubViews <> NIL THEN
  2147.         BEGIN
  2148.         fSubViews.Delete(theSubView);
  2149.         IF fSubViews.IsEmpty THEN                        { See if we need the list any more }
  2150.             BEGIN
  2151.             FreeIfObject(fSubViews);
  2152.             fSubViews := NIL;
  2153.             END;
  2154.         END;
  2155.  
  2156.     IF theSubView.fNextHandler = SELF THEN                { If next event handler is the superview }
  2157.         theSubView.fNextHandler := NIL;                 { take it out of the event handler chain. }
  2158.  
  2159.     theSubView.fSuperview := NIL;
  2160.  
  2161.     theSubView.InvalidateFocus;                        { the new subview may have been focused }
  2162.  
  2163.     { !!! Patch up the target chain.  This has to be done because we don't have any notification }
  2164.     { process.    This will have to be fixed up later. }
  2165.     itsWindow := GetWindow;
  2166.     IF (itsWindow <> NIL) & (itsWindow.fTarget = theSubView) THEN
  2167.         itsWindow.SetTarget(SELF)                        { in the next release with better }
  2168.     ELSE IF theSubView = gTarget THEN
  2169.         gApplication.SetTarget(SELF);
  2170.  
  2171.     theSubView.BeInPort(NIL);
  2172.     END;
  2173.  
  2174. {--------------------------------------------------------------------------------------------------}
  2175. {$S MANonRes}
  2176.  
  2177. PROCEDURE TView.Resize(width, height: VCoordinate;
  2178.                        invalidate: BOOLEAN);
  2179.  
  2180.     VAR
  2181.         delta:                VPoint;
  2182.         oldFrame, newFrame, InvalRect: VRect;
  2183.  
  2184.     PROCEDURE NotifySubView(theSubView: TView);
  2185.  
  2186.         BEGIN
  2187.         theSubView.SuperViewChangedSize(delta, invalidate);
  2188.         END;
  2189.  
  2190.     BEGIN
  2191.     IF (fSize.h <> width) | (fSize.v <> height) THEN
  2192.         BEGIN
  2193.         IF invalidate & Focus THEN
  2194.             GetFrame(oldFrame);
  2195.  
  2196.         SetVPt(delta, width - fSize.h, height - fSize.v);
  2197.         fSize.h := width;
  2198.         fSize.v := height;
  2199.  
  2200.         InvalidateFocus;                                {Must re-focus because size changed}
  2201.         gApplication.InvalidateCursorRgn;                {Must re-calc cursor rgn.}
  2202.  
  2203.         IF invalidate & Focus THEN
  2204.             BEGIN
  2205.             GetFrame(newFrame);
  2206.  
  2207.             IF FocusOnSuperView THEN
  2208.                 BEGIN
  2209.                 IF oldFrame.right <> newFrame.right THEN { must invalidate width difference }
  2210.                     BEGIN
  2211.                     SetVRect(InvalRect, Min(oldFrame.right, newFrame.right), Min(oldFrame.top,
  2212.                              newFrame.top), Max(oldFrame.right, newFrame.right),
  2213.                              Max(oldFrame.bottom, newFrame.bottom));
  2214.                     IF fSuperview <> NIL THEN
  2215.                         fSuperview.InvalidVRect(InvalRect);
  2216.                     END;
  2217.  
  2218.                 IF oldFrame.bottom <> newFrame.bottom THEN { must invalidate height difference }
  2219.                     BEGIN
  2220.                     SetVRect(InvalRect, Min(oldFrame.left, newFrame.left), Min(oldFrame.bottom,
  2221.                              newFrame.bottom), Max(oldFrame.right, newFrame.right),
  2222.                              Max(oldFrame.bottom, newFrame.bottom));
  2223.                     IF fSuperview <> NIL THEN
  2224.                         fSuperview.InvalidVRect(InvalRect);
  2225.                     END
  2226.                 END;
  2227.             END;
  2228.  
  2229.         IF fSuperview <> NIL THEN
  2230.             fSuperview.SubViewChangedSize(SELF, delta);
  2231.         EachSubView(NotifySubView);
  2232.         END;
  2233.     END;
  2234.  
  2235. {--------------------------------------------------------------------------------------------------}
  2236. {$S MAScroll}
  2237.  
  2238. PROCEDURE TView.RevealBottom(redraw: BOOLEAN);
  2239.  
  2240.     VAR
  2241.         rectToReveal:        VRect;
  2242.  
  2243.     BEGIN
  2244.     rectToReveal.topleft := fSize;
  2245.     rectToReveal.botRight := fSize;
  2246.     RevealRect(rectToReveal, gZeroPt, redraw);
  2247.     END;
  2248.  
  2249. {--------------------------------------------------------------------------------------------------}
  2250. {$S MAScroll}
  2251.  
  2252. PROCEDURE TView.RevealRect(rectToReveal: VRect;
  2253.                            minToSee: Point;
  2254.                            redraw: BOOLEAN);
  2255.  
  2256.     BEGIN
  2257.     IF fSuperview <> NIL THEN
  2258.         BEGIN
  2259.         OffsetVRect(rectToReveal, fLocation.h, fLocation.v);
  2260.         fSuperview.RevealRect(rectToReveal, minToSee, redraw);
  2261.         END;
  2262.     END;
  2263.  
  2264. {--------------------------------------------------------------------------------------------------}
  2265. {$S MAScroll}
  2266.  
  2267. PROCEDURE TView.RevealTop(redraw: BOOLEAN);
  2268.  
  2269.     BEGIN
  2270.     RevealRect(gZeroVRect, gZeroPt, redraw);
  2271.     END;
  2272.  
  2273. {--------------------------------------------------------------------------------------------------}
  2274. {$S MANonRes}
  2275.  
  2276. PROCEDURE TView.Show(state, redraw: BOOLEAN);
  2277.  
  2278.     BEGIN
  2279.     IF state <> fShown THEN
  2280.         BEGIN
  2281.         IF redraw THEN
  2282.             BEGIN
  2283.             fShown := TRUE;                             { So that ForceRedraw works. }
  2284.             ForceRedraw;
  2285.             END;
  2286.         InvalidateFocus;
  2287.         gApplication.InvalidateCursorRgn;                {Must re-calc cursor rgn.}
  2288.         fShown := state;
  2289.         END;
  2290.     END;
  2291.  
  2292. {--------------------------------------------------------------------------------------------------}
  2293. {$S MAReadFile}
  2294.  
  2295. PROCEDURE TView.ShowReverted;
  2296.  
  2297. {--------------------------------------------------------------------------------------------------}
  2298.  
  2299.     PROCEDURE RevertSubView(theSubView: TView);
  2300.  
  2301.         BEGIN
  2302.         theSubView.ShowReverted;
  2303.         END;
  2304.  
  2305.     BEGIN
  2306.     AdjustSize;
  2307.     ForceRedraw;
  2308.     EachSubView(RevertSubView);
  2309.     END;
  2310.  
  2311. {--------------------------------------------------------------------------------------------------}
  2312. {$S MANonRes}
  2313.  
  2314. PROCEDURE TView.SubViewChangedSize(theSubView: TView;
  2315.                                    delta: VPoint);
  2316.  
  2317.     BEGIN
  2318.     END;
  2319.  
  2320. {--------------------------------------------------------------------------------------------------}
  2321. {$S MANonRes}
  2322.  
  2323. PROCEDURE TView.SubViewMoved(theSubView: TView);
  2324.  
  2325.     BEGIN
  2326.     END;
  2327.  
  2328. {--------------------------------------------------------------------------------------------------}
  2329. {$S MAViewRes}
  2330.  
  2331. PROCEDURE TView.SuperToLocal(VAR thePoint: VPoint);
  2332.  
  2333.     BEGIN
  2334.     {$Push} {$H-}
  2335.     SubVPt(fLocation, thePoint);
  2336.     {$Pop}
  2337.     END;
  2338.  
  2339. {--------------------------------------------------------------------------------------------------}
  2340. {$S MANonRes}
  2341.  
  2342. PROCEDURE TView.SuperViewChangedSize(delta: VPoint;
  2343.                                      invalidate: BOOLEAN);
  2344.  
  2345.     VAR
  2346.         newSize:            VPoint;
  2347.         needsResizing:        BOOLEAN;
  2348.         vhs:                VHSelect;
  2349.  
  2350.     BEGIN
  2351.     needsResizing := FALSE;
  2352.     newSize := fSize;
  2353.     FOR vhs := v TO h DO
  2354.         IF fSizeDeterminer[vhs] = sizeSuperView THEN
  2355.             needsResizing := TRUE
  2356.         ELSE IF fSizeDeterminer[vhs] = sizeRelSuperView THEN
  2357.             BEGIN
  2358.             newSize.vh[vhs] := newSize.vh[vhs] + delta.vh[vhs];
  2359.             needsResizing := TRUE;
  2360.             END;
  2361.  
  2362.     IF needsResizing THEN
  2363.         BEGIN
  2364.         ComputeSize(newSize);
  2365.         Resize(newSize.h, newSize.v, invalidate);
  2366.         DoPagination;
  2367.         END;
  2368.     END;
  2369.  
  2370. {--------------------------------------------------------------------------------------------------}
  2371. {$S MANonRes}
  2372.  
  2373. PROCEDURE TView.SuperViewMoved(invalidate: BOOLEAN);
  2374.  
  2375.     BEGIN
  2376.     END;
  2377.  
  2378. {--------------------------------------------------------------------------------------------------}
  2379. {$S MADoCommand}
  2380.  
  2381. FUNCTION TView.IsDoneTracking: BOOLEAN;
  2382.  
  2383.     BEGIN
  2384.     { Default to mouse-down tracking }
  2385.     IsDoneTracking := NOT StillDown;
  2386.     END;
  2387.  
  2388. {--------------------------------------------------------------------------------------------------}
  2389. {$S MADoCommand}
  2390.  
  2391. PROCEDURE TView.TrackConstrain(anchorPoint, previousPoint: VPoint;
  2392.                                VAR nextPoint: VPoint);
  2393.  
  2394.     BEGIN
  2395.     END;
  2396.  
  2397. {--------------------------------------------------------------------------------------------------}
  2398. {$S MADoCommand}
  2399.  
  2400. PROCEDURE TView.TrackFeedback(anchorPoint, nextPoint: VPoint;
  2401.                               turnItOn, mouseDidMove: BOOLEAN);
  2402.  
  2403. { Use code like this to get a flickering rectangle. }
  2404.  
  2405.     VAR
  2406.         r:                    Rect;
  2407.         vr:                 VRect;
  2408.  
  2409.     BEGIN
  2410.     IF mouseDidMove THEN
  2411.         BEGIN
  2412.         Pt2VRect(anchorPoint, nextPoint, vr);
  2413.         ViewToQDRect(vr, r);
  2414.         PenPat(Gray);
  2415.         FrameRect(r);
  2416.         END;
  2417.     END;
  2418.  
  2419. {--------------------------------------------------------------------------------------------------}
  2420. {$S MADoCommand}
  2421.  
  2422. PROCEDURE TView.TrackMouse(aTrackPhase: TrackPhase;
  2423.                            VAR anchorPoint, previousPoint, nextPoint: VPoint;
  2424.                            mouseDidMove: BOOLEAN);
  2425.  
  2426.     BEGIN
  2427.     END;
  2428.  
  2429. {--------------------------------------------------------------------------------------------------}
  2430. {$S MAViewRes}
  2431.  
  2432. PROCEDURE TView.Update;
  2433.  
  2434.     BEGIN
  2435.     IF fSuperview <> NIL THEN
  2436.         fSuperview.Update
  2437.     ELSE
  2438.         DrawContents;
  2439.     END;
  2440.  
  2441. {--------------------------------------------------------------------------------------------------}
  2442. {$S MAViewRes}
  2443.  
  2444. PROCEDURE TView.ValidVRect(viewRect: VRect);
  2445.  
  2446.     VAR
  2447.         r:                    Rect;
  2448.  
  2449.     BEGIN
  2450.     IF Focus THEN
  2451.         BEGIN
  2452.         ViewToQDRect(viewRect, r);
  2453.         VisibleRect(r);
  2454.         ValidRect(r);
  2455.         END;
  2456.     END;
  2457.  
  2458. {--------------------------------------------------------------------------------------------------}
  2459. {$S MAViewRes}
  2460.  
  2461. PROCEDURE TView.ViewEnable(state, redraw: BOOLEAN);
  2462.  
  2463.     BEGIN
  2464.     fViewEnabled := state;
  2465.     IF redraw THEN
  2466.         ForceRedraw;
  2467.     END;
  2468.  
  2469. {--------------------------------------------------------------------------------------------------}
  2470. {$S MAViewRes}
  2471.  
  2472. FUNCTION TView.ViewToQDPt(viewPt: VPoint): Point;
  2473.  
  2474.     BEGIN
  2475.     {$IFC qDebug}
  2476.     AssumeFocused;
  2477.     {$ENDC}
  2478.  
  2479.     SubVPt(gLongOffset, viewPt);
  2480.     ViewToQDPt := VPtToPt(viewPt);
  2481.     END;
  2482.  
  2483. {--------------------------------------------------------------------------------------------------}
  2484. {$S MAViewRes}
  2485.  
  2486. PROCEDURE TView.ViewToQDRect(viewRect: VRect;
  2487.                              VAR qdRect: Rect);
  2488.  
  2489.     BEGIN
  2490.     {$IFC qDebug}
  2491.     AssumeFocused;
  2492.     {$ENDC}
  2493.  
  2494.     WITH gLongOffset DO
  2495.         OffsetVRect(viewRect, - h, - v);
  2496.     VRectToRect(viewRect, qdRect);
  2497.     END;
  2498.  
  2499. {--------------------------------------------------------------------------------------------------}
  2500. {$S MAViewRes}
  2501.  
  2502. PROCEDURE TView.WindowToLocal(VAR thePoint: VPoint);
  2503.  
  2504.     BEGIN
  2505.     IF fSuperview <> NIL THEN
  2506.         BEGIN
  2507.         fSuperview.WindowToLocal(thePoint);
  2508.         SuperToLocal(thePoint);
  2509.         END;
  2510.     END;
  2511.  
  2512. {--------------------------------------------------------------------------------------------------}
  2513. {$S MANonRes}
  2514.  
  2515. PROCEDURE TView.WriteToDeskScrap;
  2516.  
  2517.     VAR
  2518.         pHndl:                PicHandle;
  2519.         pictureIsOpen:        BOOLEAN;
  2520.         qdExtent:            Rect;
  2521.         err:                LONGINT;
  2522.         tempPort:            GrafPort;
  2523.         tempCPort:            CGrafPort;
  2524.         fi:                 FailInfo;
  2525.  
  2526.     PROCEDURE HdlWriteToDeskScrap(error: OSErr;
  2527.                                   message: LONGINT);
  2528.  
  2529.         BEGIN
  2530.         IF pHndl <> NIL THEN
  2531.             BEGIN
  2532.             IF pictureIsOpen THEN
  2533.                 ClosePicture;
  2534.             KillPicture(pHndl);
  2535.             END;
  2536.  
  2537.         IF qNeedsColorQD | gConfiguration.hasColorQD THEN
  2538.             CloseCPort(@tempCPort)
  2539.         ELSE
  2540.             ClosePort(@tempPort);
  2541.         SetPort(gWorkPort);
  2542.         BeInPort(NIL);
  2543.         gDrawingPictScrap := FALSE;
  2544.         gDrawingPictScrapView := NIL;
  2545.         END;
  2546.  
  2547.     BEGIN                                                {!!! Really need to have AsPict method to
  2548.                                                          render a view so anyone can call it }
  2549.     InvalidateFocus;
  2550.  
  2551.     gDrawingPictScrap := TRUE;
  2552.     gDrawingPictScrapView := SELF;
  2553.     IF qNeedsColorQD | gConfiguration.hasColorQD THEN
  2554.         BEGIN
  2555.         OpenCPort(@tempCPort);
  2556.         BeInPort(@tempCPort);
  2557.         END
  2558.     ELSE
  2559.         BEGIN
  2560.         OpenPort(@tempPort);
  2561.         BeInPort(@tempPort);
  2562.         END;
  2563.  
  2564.     CatchFailures(fi, HdlWriteToDeskScrap);
  2565.  
  2566.     IF Focus THEN
  2567.         BEGIN
  2568.         {Open color or black & white, depending on the port}
  2569.         GetQDExtent(qdExtent);
  2570.         pHndl := OpenPicture(qdExtent);
  2571.         pictureIsOpen := TRUE;                            { Failure handler needs to close it }
  2572.  
  2573.         IF pHndl <> NIL THEN
  2574.             BEGIN
  2575.             ClipRect(qdExtent);
  2576.             DrawContents;
  2577.             ClosePicture;
  2578.             pictureIsOpen := FALSE;                     { Failure handler doesn't need to close it }
  2579.  
  2580.       {On the 128K ROMs the picFrame will be empty if drawing the
  2581.        picture failed.    On the 64K ROM's QuickDraw simply bombs.}
  2582.             IF EmptyRect(pHndl^^.picFrame) THEN
  2583.                 BEGIN
  2584.                 {$IFC qDebug}
  2585.                 WRITELN('Picture frame is empty!');
  2586.                 {$ENDC}
  2587.                 Failure(memFullErr, 0);
  2588.                 END;
  2589.  
  2590.             err := PutDeskScrapData('PICT', Handle(pHndl));
  2591.             KillPicture(pHndl);
  2592.             pHndl := NIL;                                { So failure handler doesn't to kill it }
  2593.  
  2594.             IF err <> NoErr THEN
  2595.                 BEGIN
  2596.                 {$IFC qDebug}
  2597.                 ProgramBreak('Failed to put PICT-type scrap');
  2598.                 {$ENDC}
  2599.                 Failure(err, 0);
  2600.                 END;
  2601.             END
  2602.         ELSE
  2603.             BEGIN
  2604.             {$IFC qDebug}
  2605.             ProgramBreak('Couldn''t 0penPicture during attempt to write PICT to desk scrap');
  2606.             {$ENDC}
  2607.             Failure(memFullErr, 0);                     {Assume cause of failure was lack of memory}
  2608.             END;
  2609.  
  2610.         InvalidateFocus;
  2611.         END
  2612.         {$IFC qDebug}
  2613.     ELSE                                                { can't focus }
  2614.         ProgramBreak('Can''t focus view while writing picture to desk scrap');
  2615.     {$ENDC}
  2616.     ;
  2617.  
  2618.     Success(fi);
  2619.  
  2620.     IF qNeedsColorQD | gConfiguration.hasColorQD THEN
  2621.         CloseCPort(@tempCPort)
  2622.     ELSE
  2623.         ClosePort(@tempPort);
  2624.     SetPort(gWorkPort);
  2625.     gDrawingPictScrap := FALSE;
  2626.     gDrawingPictScrapView := NIL;
  2627.     BeInPort(NIL);
  2628.  
  2629.     END;
  2630.  
  2631. {--------------------------------------------------------------------------------------------------}
  2632. {$S MAFields}
  2633.  
  2634. PROCEDURE TView.Fields(PROCEDURE DoToField(fieldName: Str255;
  2635.                                            fieldAddr: Ptr;
  2636.                                            fieldType: INTEGER)); OVERRIDE;
  2637.  
  2638.     BEGIN
  2639.     DoToField('TView', NIL, bClass);
  2640.     DoToField('fSuperView', @fSuperview, bObject);
  2641.     DoToField('fSubViews', @fSubViews, bObject);
  2642.     DoToField('fDocument', @fDocument, bObject);
  2643.     DoToField('fLocation', @fLocation, bVPoint);
  2644.     DoToField('fSize', @fSize, bVPoint);
  2645.     DoToField('fSizeDeterminer[h]', @fSizeDeterminer[h], bSizeDeterminer);
  2646.     DoToField('fSizeDeterminer[v]', @fSizeDeterminer[v], bSizeDeterminer);
  2647.     DoToField('fHLDesired', @fHLDesired, bHLState);
  2648.     DoToField('fIdentifier', @fIdentifier, bIDType);
  2649.     DoToField('fShown', @fShown, bBoolean);
  2650.     DoToField('fViewEnabled', @fViewEnabled, bBoolean);
  2651.     DoToField('fPrintHandler', @fPrintHandler, bObject);
  2652.  
  2653.     {$IFC qExperimentalAndUnsupported}
  2654.     DoToField('fFocusRec', NIL, bTitle);
  2655.     DoToField('  isValid', @gSaveFocusRec.IsValid, bBoolean);
  2656.     DoToField('  clip', @gSaveFocusRec.Clip, bRgnHandle);
  2657.     DoToField('  drawingPictScrap', @gSaveFocusRec.drawingPictScrap, bBoolean);
  2658.     DoToField('  drawingPictScrapView', @gSaveFocusRec.drawingPictScrapView, bObject);
  2659.     DoToField('  focusedView', @gSaveFocusRec.focusedView, bObject);
  2660.     DoToField('  longOffset', @gSaveFocusRec.longOffset, bVPoint);
  2661.     DoToField('  org', @gSaveFocusRec.org, bPoint);
  2662.     DoToField('  port', @gSaveFocusRec.port, bWindowPtr);
  2663.     DoToField('  printing', @gSaveFocusRec.printing, bBoolean);
  2664.     {$EndC}
  2665.  
  2666.     INHERITED Fields(DoToField);
  2667.     END;
  2668.